我正在编写单元测试,需要将结果文件与黄金文件进行比较。最简单的方法是什么?
到目前为止,我(对于Linux环境):
int result = system("diff file1 file2");
如果result != 0
答案 0 :(得分:19)
如果你想要一个纯粹的c ++解决方案,我会做这样的事情
#include <algorithm>
#include <iterator>
#include <string>
#include <fstream>
template<typename InputIterator1, typename InputIterator2>
bool
range_equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
while(first1 != last1 && first2 != last2)
{
if(*first1 != *first2) return false;
++first1;
++first2;
}
return (first1 == last1) && (first2 == last2);
}
bool compare_files(const std::string& filename1, const std::string& filename2)
{
std::ifstream file1(filename1);
std::ifstream file2(filename2);
std::istreambuf_iterator<char> begin1(file1);
std::istreambuf_iterator<char> begin2(file2);
std::istreambuf_iterator<char> end;
return range_equal(begin1, end, begin2, end);
}
它避免将整个文件读入内存,并在文件不同时(或文件末尾)立即停止。 range_equal因为std::equal
没有为第二个范围采用一对迭代器,如果第二个范围较短则不安全。
答案 1 :(得分:3)
从DaveS's answer开始,首先是checking file size:
#include <fstream>
#include <algorithm>
bool compare_files(const std::string& filename1, const std::string& filename2)
{
std::ifstream file1(filename1, std::ifstream::ate | std::ifstream::binary); //open file at the end
std::ifstream file2(filename2, std::ifstream::ate | std::ifstream::binary); //open file at the end
const std::ifstream::pos_type fileSize = file1.tellg();
if (fileSize != file2.tellg()) {
return false; //different file size
}
file1.seekg(0); //rewind
file2.seekg(0); //rewind
std::istreambuf_iterator<char> begin1(file1);
std::istreambuf_iterator<char> begin2(file2);
return std::equal(begin1,std::istreambuf_iterator<char>(),begin2); //Second argument is end-of-range iterator
}
(我想知道在倒带之前,fileSize
是否可以用来创建一个更高效的流迭代器结尾,通过知道流长度,允许std::equal
当时处理更多字节)。
答案 2 :(得分:1)
防止读取这两个文件的一种方法是将黄金文件预先计算为哈希值,例如md5。然后你只需要检查测试文件。请注意,这可能比仅读取两个文件要慢!
或者,将检查分层 - 查看文件大小,如果它们不同则文件不同,您可以避免冗长的读取和比较操作。
答案 3 :(得分:0)
这应该有效:
#include <string>
#include <fstream>
#include <streambuf>
#include <iterator>
bool equal_files(const std::string& a, const std::string& b)
std::ifstream stream{a};
std::string file1{std::istreambuf_iterator<char>(stream),
std::istreambuf_iterator<char>()};
stream = std::ifstream{b};
std::string file2{std::istreambuf_iterator<char>(stream),
std::istreambuf_iterator<char>()};
return file1 == file2;
}
我怀疑这不如diff
快,但它避免了调用
system
。但是,对于测试用例来说应该足够了。
答案 4 :(得分:0)
可能是一个矫枉过正但你可以使用boost / bimap和boost / scope_exit建立一个哈希表SHA-256。
以下是Stephan T Lavavej如何做到这一点的视频(从8.15开始): http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Advanced-STL/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-5-of-n
有关算法的更多信息: http://en.wikipedia.org/wiki/SHA-2