【问题标题】:Do I have to seek after each read using ifstream?我是否必须在每次阅读后使用 ifstream 进行搜索?
【发布时间】:2012-10-03 19:37:32
【问题描述】:

这是我从任何大小的文件中读取的循环,并写入一个 1016 字节的 char* 数据包,每次 1016 字节,然后发送它(尚未包括发送)。

seekg() 有必要吗?或者读取是否已经将指针移动到下一个块的前面?

ifstream file (packet.message, ios::in|ios::binary|ios::ate);
if(file.is_open()) {
    size = file.tellg();
    file.seekg(0, ios::beg);
    for(int i = 0; !ios::eof; i++) {
        memset(packet.message,0,1016*sizeof(char));
        file.read(packet.message,1016*sizeof(char));
        file.seekg(i*1016*sizeof(char));
    }
}

我知道这不是写入文件的问题,因为您只需一直写入到文件末尾,直到文件大小合适。

编辑:在 if 语句中添加了全部代码。

【问题讨论】:

  • 你知道,你总是可以编译代码,运行它,看看它是否符合你的要求..
  • 还有很多其他事情正在发生。我必须制作一个单独的程序。
  • 你说创建一个C++程序好像很难。我几乎每次回答有关 C++ 的问题时都倾向于编写、编译和运行一个小程序(主要是因为我不经常使用 C++,也不想发布无法编译的代码示例)。
  • 1) 使用.eof() 作为循环条件是almost always a bad idea。 2) .eof() 是要调用的函数,而不是要测试的标志。
  • @BrendanLong 在某些情况下建议不错,但在 C 和 C++ 中,由于实现定义和未定义的行为,它经常失败。

标签: c++ file-io binaryfiles


【解决方案1】:

没必要。从上次看到文件指针的位置继续读取,就像写入一样。

【讨论】:

  • 谢谢,我想这现在可以变成一个while循环了!
  • @Portaljacker - 您可能也不需要在循环之前进行搜索。
  • @Robᵩ 我只是把它放在那里,因为它在示例中显示。在使用tellg() 保存大小之前,我没有显示该行。我假设 tellg() 移动了指针。
  • tellg() 没有,但听起来你之前有一个seekg()。在这种情况下,您可能确实需要重新开始。
  • @Robᵩ 我得到它的例子很奇怪......它做了我在例子中所做的,tellg 然后 seekg 到 0。它说 tellg 给出了指针的当前位置,这将是如果它在文件末尾,大小对吗?有问题的教程:cplusplus.com/doc/tutorial/files
【解决方案2】:

我敢打赌,文件不是在std::ios_base::binary 模式下打开的,memset()seekg() 都被用来掩盖产生的效果:尽管您可能需要清除如果读取部分记录,文件末尾的尾随字节。

顺便说一句:您总是想在 阅读后检查流的状态:

while (in.read(buffer, size)) {
    ...
}

还有:sizeof(char) == 1

【讨论】:

  • 你是说这是新写的代码?松开对seekg() 的所有调用(你甚至不使用size,更不用说它可能会给你一个错误的结果,例如,如果使用非C std::codecvt<char> 方面)。此外,松开memset():无论如何,数据都会被read() 覆盖,尽管您可能想要验证您读取了预期的数据量。 ...并且您的循环条件显然是错误的,应该是file.read(...)
  • memset 用于确保数据包在写入之前为 0。尺寸用于其他用途,但它的位置很重要,因为我必须在传输之前将尺寸发送到另一台机器。就像我说的,我没有放任何网络代码,只是在那之前将东西移动到数据包中。
  • memset() 是毫无意义的:除了最后一个数据包可能所有字节都被read() 覆盖!您可以使用gcount():while (file.read(buffer, size)) { std::fill(buffer + file.gcount(), buffer + size, 0); send(buffer, size); } 设置未写入的尾随字节。寻找文件末尾是否给你一个粗略的近似值几乎没有定义。查找的结果可用于恢复位置。搜索位置的计算确实有效,但您至少需要计算结束和开始之间的差异。
猜你喜欢
  • 2018-09-03
  • 2019-06-02
  • 2021-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
相关资源
最近更新 更多