fstream 给我错误的文件大小
fstream gives me wrong file size
我编写了将整个文件读入缓冲区的简单函数。
#include <iostream>
#include <fstream>
int main()
{
std::ios_base::sync_with_stdio(0);
std::ifstream t;
t.open("C:\Users\sufal\Desktop\test.txt");
t.seekg(0, std::ios::end);
long length = t.tellg();
t.seekg(0, std::ios::beg);
std::cout << "file size: " << length << std::endl;
char* buffer = new char[length+1];
t.read(buffer, length);
t.close();
buffer[length] = 0;
std::cout << buffer << std::endl;
return 0;
}
这是test.txt:
1
2
3
程序产生的输出如下所示:
文件大小应为 5 个字节。为什么我的程序显示错误的文件大小? Windows Explorer 似乎也显示了 7 个字节的错误文件大小。
在Windows这个文件确实是7个字节:1
\r\n
2
\r\n
3
Windows 将新行编码为两个字节 - CR + LF(或 \r
+ \n
其他表示法)。
一切正确。
在Windows上,换行符是"\r\n"
,由两个字节组成。因此,如果您的文件没有以换行符结尾,7
确实是它的大小:
1 <-- 1 byte for '1', 2 bytes for CRLF
2 <-- 1 byte for '2', 2 bytes for CRLF
3 <-- 1 byte for '3'
要在字节级别正确读取文件,您需要以二进制模式打开它:
t.open("C:\Users\sufal\Desktop\test.txt", ios_base::binary);
(您可以在 the documentation 中阅读有关此行为的详细信息)。
您还可以在 C++ 中查看将整个文件读入字符串的其他选项:
- Read file-contents into a string in C++
- Read whole ASCII file into C++ std::string
您的文件大小为 7 个字节,因为它使用了 CRLF 换行符。
1[cr][lf]
2[cr][lf]
3
但是,您在 text 模式下打开文件,Windows 会将 CRLF 换行符规范化为 LF。您正在为缓冲区分配 7 char
s,但 read()
仅输出 5 char
s:
1[lf]
2[lf]
3
这就是为什么你在打印输出的末尾看到额外的 2 =
,因为你没有将未使用的缓冲区清零 space,所以你会看到来自未初始化的随机垃圾内存。
要执行您正在尝试的操作,请改用 二进制 模式打开文件。
t.open("C:\Users\sufal\Desktop\test.txt", std::ios_base::binary);
有关详细信息,请参阅 cppreference.com 上的 Binary and text modes。
我编写了将整个文件读入缓冲区的简单函数。
#include <iostream>
#include <fstream>
int main()
{
std::ios_base::sync_with_stdio(0);
std::ifstream t;
t.open("C:\Users\sufal\Desktop\test.txt");
t.seekg(0, std::ios::end);
long length = t.tellg();
t.seekg(0, std::ios::beg);
std::cout << "file size: " << length << std::endl;
char* buffer = new char[length+1];
t.read(buffer, length);
t.close();
buffer[length] = 0;
std::cout << buffer << std::endl;
return 0;
}
这是test.txt:
1
2
3
程序产生的输出如下所示:
文件大小应为 5 个字节。为什么我的程序显示错误的文件大小? Windows Explorer 似乎也显示了 7 个字节的错误文件大小。
在Windows这个文件确实是7个字节:1
\r\n
2
\r\n
3
Windows 将新行编码为两个字节 - CR + LF(或 \r
+ \n
其他表示法)。
一切正确。
在Windows上,换行符是"\r\n"
,由两个字节组成。因此,如果您的文件没有以换行符结尾,7
确实是它的大小:
1 <-- 1 byte for '1', 2 bytes for CRLF
2 <-- 1 byte for '2', 2 bytes for CRLF
3 <-- 1 byte for '3'
要在字节级别正确读取文件,您需要以二进制模式打开它:
t.open("C:\Users\sufal\Desktop\test.txt", ios_base::binary);
(您可以在 the documentation 中阅读有关此行为的详细信息)。
您还可以在 C++ 中查看将整个文件读入字符串的其他选项:
- Read file-contents into a string in C++
- Read whole ASCII file into C++ std::string
您的文件大小为 7 个字节,因为它使用了 CRLF 换行符。
1[cr][lf]
2[cr][lf]
3
但是,您在 text 模式下打开文件,Windows 会将 CRLF 换行符规范化为 LF。您正在为缓冲区分配 7 char
s,但 read()
仅输出 5 char
s:
1[lf]
2[lf]
3
这就是为什么你在打印输出的末尾看到额外的 2 =
,因为你没有将未使用的缓冲区清零 space,所以你会看到来自未初始化的随机垃圾内存。
要执行您正在尝试的操作,请改用 二进制 模式打开文件。
t.open("C:\Users\sufal\Desktop\test.txt", std::ios_base::binary);
有关详细信息,请参阅 cppreference.com 上的 Binary and text modes。