對於一般的文件系統操作,有Boost Filesystem。
http://www.boost.org/doc/libs/1_57_0/libs/filesystem/doc/index.htm
比較就可以計算哈希值的文件和比較哈希值。對於兩個文件,將字符逐字比較,但對於比較哈希勝出的兩個以上文件,效率會更高。
爲此,有Crypto ++。
http://www.cryptopp.com/
使用兩個庫解決問題的3個問題的實施例。
// C++ standard library
#include <iostream>
// Boost
#include <boost/filesystem.hpp>
// Crypto++
#include <cryptopp/sha.h>
#include <cryptopp/hex.h>
#include <cryptopp/files.h>
using std::string;
const string file_hash(const boost::filesystem::path &file);
int main(int argc, char** argv) {
if (argc != 3)
{
std::cout << "Usage: " << argv[0] << "filepath1 filepath2\n";
return 1;
}
const string filename1(argv[1]);
const string filename2(argv[2]);
std::cout << "filename 1: " << filename1 << std::endl;
std::cout << "filename 2: " << filename2 << std::endl;
// file existence
const bool file_exists1 = boost::filesystem::exists(filename1);
const bool file_exists2 = boost::filesystem::exists(filename2);
std::cout << "file 1 exists: " << std::boolalpha << file_exists1 << std::endl;
std::cout << "file 2 exists: " << std::boolalpha << file_exists2 << std::endl;
if (!file_exists1 || !file_exists2)
return EXIT_SUCCESS;
// file size
const boost::filesystem::path file_path1(filename1);
const boost::filesystem::path file_path2(filename2);
const uintmax_t file_size1 = boost::filesystem::file_size(file_path1);
const uintmax_t file_size2 = boost::filesystem::file_size(file_path2);
std::cout << "file 1 size: " << std::boolalpha << file_size1 << std::endl;
std::cout << "file 2 size: " << std::boolalpha << file_size2 << std::endl;
// comparing files
const string hash1 = file_hash(file_path1);
const string hash2 = file_hash(file_path2);
std::cout << "hash1: " << hash1 << std::endl;
std::cout << "hash2: " << hash2 << std::endl;
const bool same_file = hash1 == hash2;
std::cout << "same file: " << same_file << std::endl;
}
const string file_hash(const boost::filesystem::path& file)
{
string result;
CryptoPP::SHA1 hash;
CryptoPP::FileSource(file.string().c_str(),true,
new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder(
new CryptoPP::StringSink(result), true)));
return result;
}
編譯我的筆記本電腦(當然目錄將是具體的,無論你有頭文件和庫,但這些自制軟件如何安裝它們在OS X):
clang++ -I/usr/local/include -L/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem demo.cpp -o demo
用法示例:
$ ./demo demo.cpp demo.cpp
filename 1: demo.cpp
filename 2: demo.cpp
file 1 exists: true
file 2 exists: true
file 1 size: 2084
file 2 size: 2084
hash1: 57E2E81D359C01DA02CB31621C9565DF0BCA056E
hash2: 57E2E81D359C01DA02CB31621C9565DF0BCA056E
same file: true
$ ./demo demo.cpp Makefile
filename 1: demo.cpp
filename 2: Makefile
file 1 exists: true
file 2 exists: true
file 1 size: 2084
file 2 size: 115
hash1: 57E2E81D359C01DA02CB31621C9565DF0BCA056E
hash2: 02676BFDF25FEA9E3A4D099B16032F23C469E70C
same file: false
如果您嘗試執行諸如獲取不存在的文件大小之類的內容,Boost Filesystem會拋出異常。您應該準備好捕獲這些異常,因此無需顯式測試文件存在,因爲您應該有一個catch塊。 (如果你想知道的是,如果一個文件存在,但你不想做這個文件的東西,那麼顯式測試存在是有意義的。)
這就是我將如何去做這些事情實踐。如果您問的是如何在沒有庫的情況下完成這些工作,那麼您可以使用C或C++標準庫來嘗試打開文件並檢查是否成功,從而檢查文件是否存在。爲了檢查文件大小,你可以打開一個文件,你可以尋找到最後,並將位置與文件的開頭進行比較。
但是,最好依靠操作系統支持來與文件系統進行通常的交互。
https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek%28%29+and+ftell%28%29+to+compute+the+size+of+a+regular+file
fstat()
例如特定於Unix和類Unix系統,並返回一個文件大小的數據包含結構,但是,微軟的系統使用GetFileSizeEx()
得到一個文件的大小。因此,如果您需要便攜式解決方案,那麼您必須使用可與各種操作系統進行交互的庫,並在操作系統中呈現一致的API。
僅使用標準庫支持比較文件可以通過實現散列函數或逐字比較文件來完成。
請參閱此處以檢查文件是否存在:http://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c – swang 2015-02-24 09:20:10
你的'if(fin.is_open())'檢查文件是否存在並且可以打開 - 我建議只添加一個'else std :: cerr <<「文件名不能被打開以便讀\ n」'。如果你不在'fin.seekp(0,std :: ios_base :: end);'(for'ofstream')或'seekg'(' ifstream'),然後是'tellp' /'tellg' ...看文檔[here](http://en.cppreference.com/w/cpp/io/basic_ostream/seekp)。 – 2015-02-24 09:35:31