如何一次从文件中读取多个字节?

时间:2010-10-06 02:33:26

标签: c++

我想一次从二进制文件中读取8byte块,直到我到达文件末尾。为什么这段代码不起作用?有哪些替代方案?

// read a file into memory
#include <iostream>
#include <fstream>
using namespace std;

int main () {

  long long int * buffer;

  ifstream is;
  is.open ("test.txt", ios::binary );

  // allocate memory:
  buffer = new long long int;

  // read data:
  while(!is.eof())
      is.read (buffer,sizeof(long long int));
  is.close();


  delete[] buffer;
  return 0;
}

如果我将所有long long int替换为char,则代码可以正常运行。

参考:代码改编自www.cplusplus.com

3 个答案:

答案 0 :(得分:3)

问题是!eof:它会告诉您上次操作是否命中了eof,不是是否会显示下一个,而 不是上次是否失败!

在执行IO之后测试流的真实性本身(或使用失败的方法,这是相同的,否定的):

while (is.read(buffer, sizeof(long long int))) {
  // use buffer
}
assert(is.fail());  // must be true

此外,您根本不必使用新内容:

long long buffer;
// ...
is.read(reinterpret_cast<char*>(&buffer), sizeof buffer)
  // the reinterpret_cast is needed in your original code too

您的来源cplusplus.com在使用数据之前也无法检查读取是否成功。一般来说,我发现该网站非常适合列出参数,方法等,对其他大多数人来说都很可怕。


将所有内容放在一起,并提供一些示例输出:

#include <climits>
#include <fstream>
#include <iomanip>
#include <iostream>

int main () {
  using namespace std;

  ifstream in ("test.txt", in.binary);
  cout << hex << setfill('0');
  for (long long buffer;
       in.read(reinterpret_cast<char*>(&buffer), sizeof buffer);)
  {
    cout << setw(sizeof buffer * CHAR_BIT / 4) << buffer << '\n';
  }

  return 0;
}

答案 1 :(得分:1)

进行缓冲区分配的另一种方法是使用union。这消除了铸造的需要。

#include <iostream>
#include <fstream>
using namespace std;

int main ()
{
    union
    {
        long long int n;
        char ch[sizeof(long long int)];
    } buffer;

    ifstream is("test.txt", ios::binary);

    while (is.read(buffer.ch,sizeof(buffer)))
        cout << buffer.n << '\n';

    return 0;
}

答案 2 :(得分:0)

char buffer[8];
while (in.read(buffer,8)) {
    long long data = *(reinterpret_cast<long long*>(buffer));
    // process data
}

这可能就是你要找的东西。