逐字节读取二进制istream

Adr*_*thy 23 c++ binaryfiles istream

我试图使用ifstream逐字节读取二进制文件.我之前使用像get()之类的istream方法一次读取二进制文件的整个块而没有问题.但是我目前的任务有助于逐字节地进行,并依靠io系统中的缓冲来提高效率.问题是我似乎比我应该更快地到达文件的末尾几个字节.所以我写了以下测试程序:

#include <iostream>
#include <fstream>

int main() {
    typedef unsigned char uint8;
    std::ifstream source("test.dat", std::ios_base::binary);
    while (source) {
        std::ios::pos_type before = source.tellg();
        uint8 x;
        source >> x;
        std::ios::pos_type after = source.tellg();
        std::cout << before << ' ' << static_cast<int>(x) << ' '
                  << after << std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会转储test.dat的内容,每行一个字节,显示前后的文件位置.

果然,如果我的文件碰巧有两个字节的序列0x0D-0x0A(对应于回车和换行),则跳过这些字节.

  • 我以二进制模式打开了流.不应该阻止它解释行分隔符吗?
  • 提取操作员总是使用文本模式吗?
  • 从二进制istream中逐字节读取的正确方法是什么?

Windows上的MSVC++ 2008.

Jam*_*nze 21

>>提取器用于格式化输入; 他们跳过空格(默认情况下).对于单字符无格式输入,您可以使用 istream::get()(int如果读取失败则返回一个EOF,或者[0,UCHAR_MAX]范围内的值)或istream::get(char&)(将参数中的字符读入,返回转换为的内容 bool,如果读取成功,如果失败则返回false.

  • 哇,令我难以置信的是,如果没有某种类型的演员,我无法从二进制文件中读取一个字节. (9认同)
  • @Ghita我认为你的意思是'std :: noskipws`. (2认同)

ste*_*anv 5

有一个read()成员函数,您可以在其中指定字节数.


Lig*_*ica 5

为什么使用格式化提取而不是.read()

  • 因为 `source &gt;&gt; x;` 比 `source.read(reinterpret_cast&lt;char *&gt;(&amp;x));` 更容易阅读,而且我没想到二进制文件上单个字节的提取运算符会执行任何操作格式化。 (8认同)
  • @cubuspl42:不过,最好避免养成使用任何 C 风格强制转换的习惯 (5认同)