【问题标题】:Binary file I/O using FILE*使用 FILE* 的二进制文件 I/O
【发布时间】:2014-06-13 00:17:37
【问题描述】:

我一直在网上搜索,实现如图所示的信息,但由于我不明白的原因,我无法让这个非常简单的代码工作。这应该是一个简单的健全性检查。我使用 FILE* 来提高速度(速度是这里的首要任务)。首先,变量...

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

int main()
{

//Declaration
int g = 1, dim_hi = 5, pop = 6;//variables I'll use to write to binary file
char OA = 'D';//variable I'll use to write to binary file

const short d_size = sizeof(double);
const short c_size = sizeof(char);
const short i_size = sizeof(int);
FILE * outFile;

int read_g = 0, read_dim = 0, read_pop = 0;//variables I'll use to READ from file
char read_oa ='a';//variable I'll use to READ from file

接下来我写入文件。据我所知(基于输出文件的大小)这部分代码工作正常。我的意图是一个接一个地向文件中写入三个整数和一个字符......

//Binary File Output
outFile = fopen ("myfile.bin", "ab");
fwrite (&dim_hi , i_size, i_size, outFile);
fwrite (&pop , i_size, i_size, outFile);
fwrite (&g , i_size, i_size, outFile);
fwrite (&OA , c_size, c_size, outFile);
fclose (outFile);

根据互联网,我应该有一个二进制文件,其中包含以下值:561D。不过根据下面的代码...

//Binary File Input
outFile = fopen ("myfile.bin", "rb");
fread ((void*)&read_dim , i_size, 1, outFile);
fread ((void*)&read_pop , i_size, 1, outFile);
fread ((void*)&read_g , i_size, 1, outFile);
fread (&read_oa , c_size, 1, outFile);
fclose (outFile);

return 0;
}

注意,我也尝试过 (char*)&read_dim,而且只是 &read_dim。我得到的是:

read_dim = 5
read_pop = -858993460
read_g = -858993460
read_oa = 9 "

我不明白。这是一个写入列表和一个读取列表。相同的系统等。为什么写入不对应于读取?我读过一些关于填充的内容,但没有一个示例使用 seekg(或 FILE* 的等效命令)对象在文件中移动。

有人知道这段代码有什么问题吗?

一旦我用这个简单的测试解决了问题,我想对矩阵的行做类似的事情(这个矩阵最终可以包含数万个元素)......

vector<vector<double> > depop(pop, vector<double> (dim_hi,0));
short v_size = dim_hi*d_size;
for(int i = 0; i < pop; i++)
{
    fwrite (&depop[i] , d_size, v_size, outFile);
}
// followed by the read command...

提前谢谢大家!

我读过的链接:

【问题讨论】:

  • 您是否查看 fwrite参数?它需要一个地址、a(单数)项目的大小、items 的数量和文件指针。因此,fwrite (&amp;dim_hi , i_size, i_size, outFile); 是错误的。看看你的第三个参数。这在您的代码中重复出现。
  • 好收获。我的后续问题是针对每个人的(因为所有的回答都是一样的)。既然我用的是 i_size, i_size 和 i_size = 4,那为什么我没有得到:read_dim = 5, read_pop = 5, read_g = 5, read_oa = garbage ??

标签: c++ c binaryfiles


【解决方案1】:

根据cplusplus.comfwrite的第三个参数是要写入的元素个数的计数,所以你应该有:

fwrite (&dim_hi , i_size, 1, outFile);
fwrite (&pop , i_size, 1, outFile);
fwrite (&g , i_size, 1, outFile);
fwrite (&OA , c_size, 1, outFile);

与您对fread 的验证调用相匹配,因为i_size 很可能大于1(int 的典型大小为4)。

【讨论】:

  • 使用fwrite(&amp;x, sizeof x, 1, outFile); 会更好。那么写入正确的字节数就毫无疑问了。
  • 我还要补充一点,使用"ab" 模式打开文件意味着您永远不会覆盖程序第一次运行时写入的内容。
【解决方案2】:

您的问题是您传递给fwrite 的第三个参数不正确。见:

fwrite (&dim_hi , i_size, i_size /* <-- here */, outFile);

fwrite 上的手册页说:

// The function fwrite() writes nmemb elements of data, each size bytes long...
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

这意味着你需要告诉每个元素的大小,以及你想写多少元素。 从您的代码中,很明显您只想编写 1 个元素。所以你应该这样做:

fwrite (&dim_hi , i_size, 1 /* <-- here */, outFile);

【讨论】:

    【解决方案3】:

    这里有两个很好的答案,我有一个评论。如果您要进行大量二进制输入/输出,请为您的平台选择一个好的十六进制编辑器。在这种情况下,您可以打开您创建的文件并检查数据是否正确。使用您的数据(并假设您希望看到 32 位 little-endian 架构):

    0x05 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x44

    作为文件的唯一内容。您的里程可能会有所不同,但我发现查看文件的内容很有帮助(以及更好的完整性检查)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-12
      • 1970-01-01
      • 2014-07-06
      • 2016-06-15
      • 2015-01-29
      • 1970-01-01
      • 2012-05-28
      • 2012-05-05
      相关资源
      最近更新 更多