gpt4 book ai didi

c - Windows 上的 read() 系统调用无法读取二进制文件

转载 作者:可可西里 更新时间:2023-11-01 09:56:28 25 4
gpt4 key购买 nike

我想读取图像文件以将它们保存在内存中,然后再将它们与 SDL 一起使用。我刚刚意识到 Windows 上的 open() 和 read() 无法完全读取我的文件,但在 linux/BSD 上却可以!

这是我的代码:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#define IMGPATH "rabbit.png"

int
main(int argc, char *argv[])
{
int fd;
struct stat st;
void *data;
size_t nbread;

fd = open(IMGPATH, O_RDONLY);
if (fd < 0)
exit(1);

fstat(fd, &st);

data = malloc(st.st_size);
if (data == NULL)
exit(1);

nbread = read(fd, data, st.st_size);
if (nbread != st.st_size)
printf("Failed to read completely: expected = %ld, read = %ld\n", st.st_size, nbread);
}

在 Windows 上它将产生:无法完全读取:预期 = 19281,读取 = 5。perror() 表示没有错误,如果我再次尝试读取 (),它不会改变并停留在这 5 个字节。

我应该向 open() 添加一些标志来读取二进制文件吗?

这是我尝试读取的第一个 PNG 字节文件:

0000000 211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R
0000010 \0 \0 \0 \ \0 \0 \0 k \b 006 \0 \0 \0 <FA> 220 <E5>

出现'\n'时是否停止读取?

我现在不知道如何解决这个问题。

PS:请不要说“使用 libpng”,因为我只需要在将文件缓冲区用于 SDL 和我的图形库之前将其放入内存即可。

最佳答案

几点:

  1. read() 不保证读取指定的字节数。它可能会提早返回或根本不会返回。必须多次调用 read() 来填充大缓冲区是正常的。这是 stdio 的原因之一。 wrapper 和 fread()很有用。

  2. 在 Windows 上,文本和二进制模式不同。由于您没有在标志中指定 O_BINARY,因此 Windows 将以不同方式处理此文件的 '\n' 字符。它可能会在遇到第一个 '\n' 时返回。

  3. 没有必要在读取文件之前检查文件大小。 read() 以及实际上任何围绕 read() 的包装器将始终在文件末尾停止读取。

更新0

进一步观察,我发现第 5 个和第 6 个字符是 \r\n,这是 Windows 在文本模式下专门处理的,并解释了我上面提到的提前返回。如果您不将 O_BINARY 传递给 open() 调用,这两个字符将被转换为单个 \n

关于c - Windows 上的 read() 系统调用无法读取二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7182957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com