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 chars,但 read() 仅输出 5 chars:

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