【问题标题】:std::ifstream::read() reading less than requested and setting failbit for no obvious reasonstd::ifstream::read() 读取少于请求并无明显原因设置故障位
【发布时间】:2015-09-27 10:34:02
【问题描述】:

我试图使用 std::ifstream 将整个文件读入缓冲区,但没有明显的原因失败,因此我构建了一个最小的代码示例来演示该问题:

std::vector<char> vec;
vec.resize(1000);
std::ifstream file("G:/Pictures/Webcam/Snapshot_20110209.jpg");
file.exceptions(std::ifstream::badbit | std::ifstream::failbit | std::ifstream::eofbit);
std::cout << file.good() << std::endl;
try {
    file.read(vec.data(), 100);
} catch (std::ios_base::failure f) {
    std::cout << f.what() << " Characters extracted: " << file.gcount() << std::endl;
} catch (...) {
    std::cout << "Some other error" << std::endl;
}
std::cout << "Done" << std::endl;
file.close();

我要读取的文件大小为 48kb,因此读取 100 字节应该不是问题。 1000 字节大的缓冲区,所以这也应该没问题。现在,流只读取了 61 个字节,然后设置了故障位。生成的输出如下:

1
ios_base::failbit set: iostream stream error Characters extracted: 61
Done

所以由于某种原因,失败位设置在 61 个字节之后。如果我读取的字节数少于 61,它就可以工作。如果我尝试阅读更多内容,它也会在 61 处失败。我还尝试了其他类似大小的文件,同样的问题。一些不同大小的完全不同的文件表现出相同的行为,但在 166 字节之后。

现在,如果我使用 Qt 的 QFile 类来读取数据,一切正常,我可以读取完整的文件。代码如下所示:

QFile file(path);
std::vector<char> buffer;
buffer.resize(file.size());
if (!file.open(QIODevice::ReadOnly)) return;
file.read(buffer.data(), file.size());
file.close();

我知道,现在你会说我只读取文件大小的大小,但实际上超过 61 个字节。同样读取固定的100也没问题。

【问题讨论】:

  • 试试std::ifstream file("G:/Pictures/Webcam/Snapshot_20110209.jpg", ios_base::binary);

标签: c++ file buffer istream


【解决方案1】:
std::ifstream file("G:/Pictures/Webcam/Snapshot_20110209.jpg");

哎呀!您正在以文本模式打开文件。

根据您的平台,任何数量的讨厌的二进制字符都可能使流认为数据流已经结束,因为不同的平台使用不同的“标记字符”来表示这一点(例如 Ctrl+Z 或 Windows 上的 0x1A — 是第 62 字节有 0x1A 吗?1)。

这里:

std::ifstream file("G:/Pictures/Webcam/Snapshot_20110209.jpg", std::ios::binary);

1 我在那个位置有一个带有0x05 的JPEG 文件;快速浏览an EXIF format description 让我觉得我们都在查看描述水平分辨率编码的TIFF 数据字段,因为0x1A010x0500 是常用选项。

【讨论】:

  • 天哪,我真是个傻瓜。非常感谢,那肯定已经完全从我的脑海中抹去,我以前用过。不知何故,我设法在我的互联网研究中避免了有关该标志的任何信息,也没有想到只查看我的一些旧代码......
  • @user1488118:别担心;从字面上看,三天前我意识到我在生产中使用了五年的库代码中存在相同的错误。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多