2010-07-05 6 views
10

Estoy tratando de leer datos binarios en un programa C con read() pero la prueba EOF no funciona. En cambio, sigue corriendo por siempre leyendo el último bit del archivo.¿Cómo se usa read() para leer datos hasta el final del archivo?

#include <stdio.h> 
#include <fcntl.h> 
int main() { 

    // writing binary numbers to a file 
    int fd = open("afile", O_WRONLY | O_CREAT, 0644); 
    int i; 
    for (i = 0; i < 10; i++) { 
    write(fd, &i, sizeof(int)); 
    } 
    close(fd); 

    //trying to read them until EOF 
    fd = open("afile", O_RDONLY, 0); 
    while (read(fd, &i, sizeof(int)) != EOF) { 
    printf("%d", i); 
    } 
    close(fd); 
} 
+2

No es el problema imediate (leer devuelve 0, no EOF) pero es probable que debe adquirir el hábito de compilar con gcc -Wall', tomar nota de las advertencias (y fijarlos!), y '#include ' cuando se usa 'read' /' write'. –

+0

gracias por el consejo, que tienen que incluirse en el código principal, donde lo que necesitaba esto, pero va a usar el -Wall también a partir de ahora :) – sekmet64

Respuesta

17

read devuelve el número de caracteres que leyó. Cuando llegue al final del archivo, no podrá leer más (en absoluto) y devolverá 0, no EOF.

+0

uf: S no sé cómo no se me olvida que en el manual, estado leyendo acerca en los últimos 20 minutos ¡Gracias! – sekmet64

+0

Bueno, puedo ver cómo no es obvio. Después de todo, uno podría pensar en muchas razones por las cuales se pueden leer 0 bytes. La clave es que cuando se lee encuentra un error, siempre _ devuelve -1, y nunca 0. devuelve 0 es correcto, final del archivo. AFAICT, incluso para IO sin bloqueo, donde es posible, y a veces muy probable que se lean 0 bytes, 0 solo se devuelve cuando se alcanza EOF. El resto del tiempo, cuando hay cero bytes para leer y EOF _no_ se ha alcanzado, se devuelve -1 y errno = EAGAIN. Al menos eso es lo que yo entiendo. – enigmaticPhysicist

2

Debe comprobar si hay errores. ¡En algunos errores (comunes) a los que desea llamar, vuelva a leer!

Si leer() devuelve -1 usted tiene que comprobar errno para el código de error. Si es igual a errno cualquiera EAGAIN o EINTR, desea reiniciar la llamada read(), sin necesidad de utilizar sus valores (incompleta) devueltos. (En otros errores, tal vez desea salir del programa con el mensaje de error correspondiente (de strerror))

Ejemplo: a wrapper called xread() from git's source code

0

retorno POSIX rasys == 0 para el final del archivo

http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html

Si ningún proceso tiene la tubería abierta para escritura, read() devolverá 0 para indicar el final del archivo.

Esto confirma Jerry's answer.

EOF se devuelve por algunas funciones ANSI, por ejemplo man getc dice:

fgetc(), getc() y getchar() devuelven el carácter leído como un unsigned char modelado a un int o EOF al final del archivo o error.

ungetc() devuelve c en caso de éxito, o EOF en caso de error.

por lo que aún no puede usarlo para distinguir el error y el final del archivo, en ese caso, es necesario feof.

Consulte también: How to use EOF to run through a text file in C?

Cuestiones relacionadas