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:
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 callread()
several times to fill large buffers. This is one of the reasons the stdio wrappers andfread()
are useful.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.It's not necessary to check the file size before reading the file. The
read()
and indeed any wrapper aroundread()
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
.
精彩评论