开发者

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. I just realized that open() and read() on windows fails to read my file entirely but on linux/BSD it works!

This is my code:

#include <fcntl.h>
#include 开发者_JAVA技巧<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.

Is there some flag I should add to open() to read binary file?

This is the first PNG bytes file I try to read:

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?

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.


A few points:

  1. read() is not guaranteed to read the count of bytes specified. It may return early or nothing at all. It's normal to have to call read() several times to fill large buffers. This is one of the reasons the stdio wrappers and fread() are useful.

  2. On Windows, text and binary mode differ. Since you did not specifiy O_BINARY in your flags, Windows will handle '\n' characters differently for this file. Likely it is returning at the first '\n' encountered.

  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.

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. If you don't pass O_BINARY to the open() call these 2 characters will be converted to a single \n.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜