简体   繁体   English

Windows上的read()syscall无法读取二进制文件

[英]read() syscall on windows fails to read binary file

I would like to read image file to keep them in memory before using them with SDL. 我想在与SDL结合使用之前读取图像文件以将其保留在内存中。 I just realized that open() and read() on windows fails to read my file entirely but on linux/BSD it works! 我只是意识到Windows上的open()和read()无法完全读取我的文件,但是在linux / BSD上它可以工作!

This is my code: 这是我的代码:

#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);
}

On windows it will produce: Failed to read completely: expected = 19281, read = 5. perror() says no error and if I try to read() again it does not change and stuck at this 5 byte. 在Windows上将产生:无法完全读取:预期= 19281,读取=5。perror()表示没有错误,如果我再次尝试read(),它不会更改并停留在这5个字节。

Is there some flag I should add to open() to read binary file? 我应该添加一些标志到open()来读取二进制文件吗?

This is the first PNG bytes file I try to read: 这是我尝试读取的第一个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>

Does it stops reading when '\\n' appears? 出现“ \\ n”时,它会停止读取吗?

I don't know how to fix this right now. 我现在不知道该如何解决。

PS: please do not says "use libpng" because I just need to get the file buffer into memory before using it with SDL and my graphic library. PS:请不要说“ use libpng”,因为在将它与SDL和图形库一起使用之前,我只需要将文件缓冲区放入内存即可。

A few points: 几点:

  1. read() is not guaranteed to read the count of bytes specified. read()不能保证读取指定的字节数。 It may return early or nothing at all. 它可能会提早返回或根本不返回。 It's normal to have to call read() several times to fill large buffers. 通常必须多次调用read()来填充大缓冲区。 This is one of the reasons the stdio wrappers and fread() are useful. 这是stdio包装程序和fread()有用的原因之一。

  2. On Windows, text and binary mode differ. 在Windows上,文本模式和二进制模式不同。 Since you did not specifiy O_BINARY in your flags, Windows will handle '\\n' characters differently for this file. 由于未在标志中指定O_BINARY ,因此Windows将对此文件使用不同的'\\n'字符处理方式。 Likely it is returning at the first '\\n' encountered. 它可能会在遇到的第一个'\\n'处返回。

  3. It's not necessary to check the file size before reading the file. 读取文件之前无需检查文件大小。 The read() and indeed any wrapper around read() will always stop reading at the end of the file. read()以及所有围绕read()包装器将始终在文件末尾停止读取。

Update0 Update0

On further observation I see that the 5th and 6th characters are \\r\\n , this is handled specially by Windows when in text mode, and explains the early return as I mentioned above. 进一步观察,我发现第5个和第6个字符是\\r\\n ,这是Windows在文本模式下专门处理的,并如上所述解释了早期返回。 If you don't pass O_BINARY to the open() call these 2 characters will be converted to a single \\n . 如果您没有将O_BINARY传递给open()调用,则这两个字符将被转换为单个\\n

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM