Ifstream 读取特定大小失败(与文件大小无关)
Ifstream read fails at a specific size (unrelated to file size)
我正在尝试读取一个文件,但我意识到它会失败,因为我会尝试读取太多数据,即使该文件比我尝试读取的文件大得多。
文件大小为 120 MB,我的 ifstream 在 12967 字节时失败(尽管它在 12801 时开始表现得很奇怪。
这是说明我的问题的代码:
#include <fstream>
#include <iostream>
#include <Windows.h>
using std::ifstream;
using std::cout;
#define CORRECT_SIZE 12800
#define CORRECT_BUT_WIERD 12966
#define INCORRECT_SIZE 12967
bool check_error_bits(ifstream* f);
int main()
{
ifstream myFile("myfile.txt");
char c[CORRECT_SIZE];
char c2[CORRECT_BUT_WIERD];
char c3[INCORRECT_SIZE];
/*
* TEST A (works fine)
*/
myFile.seekg(0, std::ios_base::beg);
myFile.read(c, CORRECT_SIZE);
check_error_bits(&myFile);
cout << myFile.tellg() << std::endl; // Here, tellg() returns 12800
/*
* TEST B (works too, but acts wierd)
*/
myFile.seekg(0, std::ios_base::beg);
myFile.read(c2, CORRECT_BUT_WIERD);
check_error_bits(&myFile);
cout << myFile.tellg() << std::endl; // Here, tellg() returns 16896
/*
* TEST C (FAIL)
*/
myFile.seekg(0, std::ios_base::beg);
myFile.read(c3, INCORRECT_SIZE);
check_error_bits(&myFile);
cout << myFile.tellg() << std::endl; // Here, tellg() returns -1
system("pause");
}
bool check_error_bits(ifstream* f)
{
bool stop = false;
if (f->eof())
{
char msg[500];
strerror_s(msg, errno);
cout << "1: " << msg << std::endl;
}
if (f->fail())
{
char msg[500];
strerror_s(msg, errno);
cout << "2: " << msg << std::endl;
stop = true;
}
if (f->bad())
{
char msg[500];
strerror_s(msg, errno);
cout << "3: " << msg << std::endl;
stop = true;
}
return stop;
}
尝试读取小于 12800 字节的内容效果很好。从128001到12966,都是可以的(虽然我没有查过数据是否正确),但是tellg()returns是无意义的。 12966之后,读取就失败了。
该程序的控制台输出是:
12800
16896
1: No error
2: No error
-1
Press any key to continue . . .
如有任何帮助,我们将不胜感激!
您有一个 16,896 字节的文件。第一次阅读效果很好。第二次读取遇到文件末尾,只能读取 16,896 字节。您的第三次读取失败,因为您没有清除流中的文件结束标志。
您可能还有一个 120MB 的文件,但这无关紧要。检查代码中文件的大小。 (或者它可能是 120MB 的二进制数据,但您正在以文本模式阅读它。)
你写了
(although I have not checked if the data is correct)
这样做,因为我认为数据是正确的。
我假设您使用的是 windows,所以:
Why can't Explorer decide what size a file is?
在Windows环境和文本文件中,取值为26=0x1A=^Z的字符作为"end fo file".
因此,如果文件不是以二进制打开,即使文件更大,也可能会收到意外的 eof。
参见维基百科 "End of file" (https://en.wikipedia.org/wiki/End-of-file):
在 Microsoft 的 DOS 和 Windows(以及在 CP/M 和许多 DEC 操作系统中),从终端读取永远不会产生 EOF。相反,程序会识别源是终端(或其他 "character device")并将给定的保留字符或序列解释为文件结束指示符;最常见的是 ASCII Control-Z,代码 26。
我正在尝试读取一个文件,但我意识到它会失败,因为我会尝试读取太多数据,即使该文件比我尝试读取的文件大得多。
文件大小为 120 MB,我的 ifstream 在 12967 字节时失败(尽管它在 12801 时开始表现得很奇怪。
这是说明我的问题的代码:
#include <fstream>
#include <iostream>
#include <Windows.h>
using std::ifstream;
using std::cout;
#define CORRECT_SIZE 12800
#define CORRECT_BUT_WIERD 12966
#define INCORRECT_SIZE 12967
bool check_error_bits(ifstream* f);
int main()
{
ifstream myFile("myfile.txt");
char c[CORRECT_SIZE];
char c2[CORRECT_BUT_WIERD];
char c3[INCORRECT_SIZE];
/*
* TEST A (works fine)
*/
myFile.seekg(0, std::ios_base::beg);
myFile.read(c, CORRECT_SIZE);
check_error_bits(&myFile);
cout << myFile.tellg() << std::endl; // Here, tellg() returns 12800
/*
* TEST B (works too, but acts wierd)
*/
myFile.seekg(0, std::ios_base::beg);
myFile.read(c2, CORRECT_BUT_WIERD);
check_error_bits(&myFile);
cout << myFile.tellg() << std::endl; // Here, tellg() returns 16896
/*
* TEST C (FAIL)
*/
myFile.seekg(0, std::ios_base::beg);
myFile.read(c3, INCORRECT_SIZE);
check_error_bits(&myFile);
cout << myFile.tellg() << std::endl; // Here, tellg() returns -1
system("pause");
}
bool check_error_bits(ifstream* f)
{
bool stop = false;
if (f->eof())
{
char msg[500];
strerror_s(msg, errno);
cout << "1: " << msg << std::endl;
}
if (f->fail())
{
char msg[500];
strerror_s(msg, errno);
cout << "2: " << msg << std::endl;
stop = true;
}
if (f->bad())
{
char msg[500];
strerror_s(msg, errno);
cout << "3: " << msg << std::endl;
stop = true;
}
return stop;
}
尝试读取小于 12800 字节的内容效果很好。从128001到12966,都是可以的(虽然我没有查过数据是否正确),但是tellg()returns是无意义的。 12966之后,读取就失败了。
该程序的控制台输出是:
12800
16896
1: No error
2: No error
-1
Press any key to continue . . .
如有任何帮助,我们将不胜感激!
您有一个 16,896 字节的文件。第一次阅读效果很好。第二次读取遇到文件末尾,只能读取 16,896 字节。您的第三次读取失败,因为您没有清除流中的文件结束标志。
您可能还有一个 120MB 的文件,但这无关紧要。检查代码中文件的大小。 (或者它可能是 120MB 的二进制数据,但您正在以文本模式阅读它。)
你写了
(although I have not checked if the data is correct)
这样做,因为我认为数据是正确的。
我假设您使用的是 windows,所以: Why can't Explorer decide what size a file is?
在Windows环境和文本文件中,取值为26=0x1A=^Z的字符作为"end fo file".
因此,如果文件不是以二进制打开,即使文件更大,也可能会收到意外的 eof。
参见维基百科 "End of file" (https://en.wikipedia.org/wiki/End-of-file):
在 Microsoft 的 DOS 和 Windows(以及在 CP/M 和许多 DEC 操作系统中),从终端读取永远不会产生 EOF。相反,程序会识别源是终端(或其他 "character device")并将给定的保留字符或序列解释为文件结束指示符;最常见的是 ASCII Control-Z,代码 26。