2017-01-18 18 views
2
#include <fstream> 
#include <string> 
#include <cassert> 

long long GetFileSizeA(const std::string& file_path) 
{ 
    return std::ifstream 
    { 
     file_path, std::ios::ate  
    }.tellg(); 
} 

long long GetFileSizeB(const std::string& file_path) 
{ 
    return std::ifstream 
    { 
     file_path, std::ios::ate | std::ios::binary 
    }.tellg(); 
} 

int main() 
{ 
    auto a = GetFileSizeA("~/test.log"); 
    auto b = GetFileSizeB("~/test.log"); 

    assert(a == b); // always true? 
} 

如果文件~/test.log包含許多\r\n序列,並在C++標準保證GetFileSizeA相同GetFileSizeB我必須在[ios :: binary]模式下打開一個文件來獲得它的大小嗎?

回答

1

標準確實決不保證兩者相等(也沒有C或C++標準狀態文件是否含有\r\n\n\r作爲行結束,在由操作系統和/或應用程序定義。標準C庫以及擴展C++庫可以保證,如果您以文本模式讀取文件,它將會將所有實際的行結束符轉換爲內部格式)。它也不能保證它總是不一樣的值。

更重要的是,您可能會發現,如果您閱讀文件的某些部分並詢問「我在哪裏」,那麼如果您讀取爲二進制文件或ascii文件,答案會有所不同。例如,如果您計劃將文件映射到內存並將其作爲大字符處理,而不翻譯換行符,則需要將其作爲二進制文件執行。

1

C++標準沒有這樣的保證。

實際上,代碼

std::ifstream{file_path, std::ios::ate | std::ios::binary}.tellg(); 

不能保證工作打算,要麼。基於文件的流上的操作歸結爲幾個中間函數(std::basic_istream::tellgstd::basic_streambuf::pubseekoffstd::basic_filebuf::seekoff)並且使用''如同'制定爲std::fseek()。後者isn't required to support seeking in binary streams relative to the end position

int fseek(std::FILE* stream, long offset, int origin);

設置文件流流的文件位置指示器。

如果流是二進制模式打開時,新的位置恰好是 偏移從該文件的開始時測量的字節如果原點是 SEEK_SET,從當前文件位置是否起源是SEEK_CUR, 並從端部該文件如果來源是SEEK_END二進制流 不需要支持SEEK_END,特別是如果輸出附加的 空字節

相關問題