一次读取一个二进制文件1个字节

时间:2011-05-23 05:37:24

标签: c file io binary

我试图一次读取一个C 1字节的二进制文件,在网上搜索几个小时后,我仍然无法检索除垃圾和/或seg故障之外的任何内容。基本上,二进制文件的格式为256项长度,每个项目为1个字节(0到255之间的无符号整数)。我试图使用fseek和fread跳转到二进制文件中的“索引”并检索该值。我目前的代码:

unsigned int buffer;

int index = 3; // any index value

size_t indexOffset = 256 * index;
fseek(file, indexOffset, SEEK_SET);
fread(&buffer, 256, 1, file);

printf("%d\n", buffer);

现在这段代码给了我随机的垃圾数和段错误。有关如何使其正常工作的任何提示?

5 个答案:

答案 0 :(得分:16)

在您的代码中,您尝试将256个字节读取到一个int的地址。如果您想一次读取一个字节,请拨打fread(&buffer, 1, 1, file);(请参阅fread)。

但更简单的解决方案是声明一个字节数组,一起读取并在此之后处理它。

答案 1 :(得分:14)

int int 混淆的字节字节的常用术语是 unsigned char 。大多数字节都是8位宽。如果您正在读取的数据是8位,则需要读取8位:

#define BUFFER_SIZE 256

unsigned char buffer[BUFFER_SIZE];

/* Read in 256 8-bit numbers into the buffer */
size_t bytes_read = 0;
bytes_read = fread(buffer, sizeof(unsigned char), BUFFER_SIZE, file_ptr);
// Note: sizeof(unsigned char) is for emphasis

将所有数据读入内存的原因是为了保持I / O流动。无论请求的数量如何,每个输入请求都会产生开销。一次读一个字节,或一次寻找一个位置是最坏的情况。

以下是读取1个字节所需的开销示例:

Tell OS to read from the file.
OS searches to find the file location.
OS tells disk drive to power up.
OS waits for disk drive to get up to speed.
OS tells disk drive to position to the correct track and sector.
-->OS tells disk to read one byte and put into drive buffer.
OS fetches data from drive buffer.
Disk spins down to a stop.
OS returns 1 byte to your program.

在您的程序设计中,上述步骤将重复256次。根据每个人的建议,标有“ - >”的行将读取256个字节。因此,开销只执行一次而不是256次,以获得相同数量的数据。

答案 2 :(得分:3)

unsigned char buffer; // note: 1 byte
fread(&buffer, 1, 1, file);

现在是时候阅读我相信的人了。

答案 3 :(得分:1)

您正在尝试将256个字节读入名为“buffer”的4字节整数变量中。您正在覆盖其他252个字节的其他数据。

似乎buffer应该是unsigned char buffer[256];,或者您应该fread(&buffer, 1, 1, f)buffer unsigned char buffer;应该是buffer

或者,如果您只想要一个字符,则可以将int保留为buffer = fgetc(f); unsigned 不需要,因为C99保证了普通int的合理最小范围)并简单地说:

{{1}}

答案 4 :(得分:0)

代码存在的几个问题。

fread的原型是:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

您已将大小设置为256(字节)并将计数设置为1.这很好,这意味着“读取一个256字节的块,将其推入缓冲区”。

但是,您的缓冲区大约为2-8个字节(或者,至少远小于256个字节),因此您有缓冲区溢出。您可能想要使用fred(& buffer,1,1,file)。

此外,您正在将字节数据写入int指针。这将适用于一个endian-ness(实际上是小端),因此你可以在英特尔架构上做得很好,并从中学习坏习惯,这些日子会回来咬你。

尝试很难将字节数据写入字节组织存储,而不是写入整数或浮点数。