windows c++ 流读取文件长度 ios::in ios::binary

问题描述:

  当用ios::in模式打开文件时,使用seekg和tellg读取文件的长度,将读取文件内容输出到控制台,发现乱码。

 1 int _tmain(int argc, _TCHAR* argv[])
 2 {
 3     using namespace std;
 4     ifstream stream("F:\\WorkSpace\\StreamDemo\\Debug\\abc.txt", ios::in);
 5     if(!stream)
 6         cerr << "Open failed" << endl;
 7     stream.seekg(0, ios::end);
 8     int len = stream.tellg();
 9     stream.seekg(0, ios::beg);
10     char* buffer = new char[len];
11     memset(buffer, '\0', len);
12     if(!stream.read(buffer, len))
13     {
14         cout << "Read error:" << stream.rdstate() << endl;
15     }
16     cout.write(buffer, len);
17     stream.close();
18     system("pause");
19     return 0;
20 }

abc.txt文件内容:

windows c++ 流读取文件长度 ios::in ios::binary_第1张图片  

运行结果如下:

windows c++ 流读取文件长度 ios::in ios::binary_第2张图片

读出结果错误,输出到控制台文件,最后有两个乱码。

而将ios::in改为ios::binary之后,运行结果如下

windows c++ 流读取文件长度 ios::in ios::binary_第3张图片

单步调试发现,得到的len为8,而文件中的内容本以为是a\naaa\n,应该是6个。

经调查,发现在windows的文本文件中换行是两个字符\r\n,所以文件中的内容为a\r\naaa\r\n这8个字符。

而用ios::in方式读入的文件为a\naaa\n,所以len超过文件末尾。

而用ios::binary方式读入的文件为a\r\naaa\r\n,得到正确的结果。

又改使用了get()来获得结果,依然发现得到的结果是a\naaa\n。

 

得出以下结论:

1. 以ios::in方式读入的文件,/r/n读取内存之后会被认为是同一个字符/n,/n写入文件变成/r/n

2. 以ios::binary方式读取的文件,/r/n读取内存之后会被认为是两个字符,写入文件时,必须把换行符写入为/r/n,否则起不到换行效果。

3. 上述seekg和tellg的方式,用作计算ios::in方式打开的文件长度,实际值大于文件读入之后的长度。不能用read读取文件,可用get或getline代替。

 

尚没有找到简单完美的方式解决流读取文件大小的问题,如果你有好的方法,请回复。

转载于:https://www.cnblogs.com/chjtao/p/4670556.html

你可能感兴趣的:(windows c++ 流读取文件长度 ios::in ios::binary)