[英]Why does this code always return file size zero?
為什么,當我使用下面的代碼片段時,無論文件大小如何,結果為零,但是當我在open()
刪除ios::binary
,它會做它應該做的事情?
fstream f1;
streampos begin, end;
f1.open("file1", ios::binary);
f1.seekg(0, ios::beg);
begin = f1.tellg();
f1.seekg(0, ios::end);
end = f1.tellg();
f1.close();
cout << end - begin << endl;
我假設通過“當我刪除ios::binary
”時你意味着刪除整個參數:
f1.open("file1");
open()
函數有兩個參數 - 文件名和模式。 模式1的默認參數為std::ios_base::in | std::ios_base::out
std::ios_base::in | std::ios_base::out
。 因此,如果您沒有指定任何內容,則會使用此deault。
但是,如果指定ios::binary
,則替換默認參數。 因為你既沒有指定in
,也不out
,在open()
調用失敗。 在open()
if()
周圍放一個if()
會告訴你 - 記住你應該總是用I / O檢查錯誤。
std::ios_base::binary
本身不是std::basic_fstream
的有效std::basic_fstream
。 有效的openmode組合可以在表132中找到:
std::basic_fstream
的構造函數及其open()
方法都通過rdbuf()->open(s, mode)
轉發內部std::basic_filebuf
上的open()
方法rdbuf()->open(s, mode)
其中mode
是openmode。 從表中可以看出, mode
(其中mode是ios_base::binary
)本身並不是一個有效的標志。 當文件緩沖區確定此時,打開失敗:
NTBS
modstr
由mode & ~ios_base::ate
modstr
mode & ~ios_base::ate
確定,如表132所示。如果mode
不是表中顯示的某些標志組合,則open打開失敗。
原因mode
不與out | in
按位OR運算 out | in
打開文件時,因為不清楚是否要將流用於輸入或輸出(它假定您知道您想要什么)。 由於模式不是有效的標志組合,因此std::basic_filebuf::open()
返回空指針。 這由流接收,而流又調用setstate(std::ios_base::failbit)
。
[..]調用
rdbuf()->open(s, mode)
。 如果該函數返回空指針,則調用setstate(failbit)
。
當流處於失敗狀態時,其tell
方法返回-1
。 這就是為什么你在減去時得到0
的原因。
如果你想要的只是大小,這是打開它的正確方法:
std::fstream f1("file1", std::ios_base::in | std::ios_base::ate | std::ios_base::binary);
std::cout << f1.tellg();
如果您的大小為0,請檢查文件是否已打開...
#include<iostream>
#include<fstream>
using namespace std;
int main(){
fstream f1;
streampos begin, end;
f1.open("Data.txt", ios::binary);
if (f1.is_open()) {
cout << "Open" << endl;
}
f1.seekg(0, ios::beg);
begin = f1.tellg();
f1.seekg(0, ios::end);
end = f1.tellg();
f1.close();
cout << end - begin << endl;
system("pause");
}
如果它沒有打開,您可能已經嘗試打開文本文件。
在文本文件中,ios :: binary標志不包含在打開模式中。 文本文件用於存儲文本數據,當對它們進行二進制輸入/輸出操作時,這可能導致格式轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.