read () ne lit que quelques octets du fichier

Je voulais lire le contenu d’un fichier en utilisant la fonction read (). J’ai essayé ce qui suit:

#define BUFFER_LENGTH (1024) char buffer[BUFFER_LENGTH]; // The first version of the question had a typo: // void read_file(const char filename) // This would produce a comstackr warning. void read_file(const char *filename) { ssize_t read_bytes = 0; // The first version had the mode in hex instead of octal. // // int fd_in = open(filename, O_RDONLY, 0x00644); // // This does not cause problems here but it is wrong. // The mode is now octal (even if it is not needed). int fd_in = open(filename, O_RDONLY, 0644); if (fd_in == -1) { return; } do { read_bytes = read(fd_in, buffer, (size_t) BUFFER_LENGTH); printf("Read %d bytes\n", read_bytes); // End of file or error. if (read_bytes <= 0) { break; } } while (1); close(fd_in); } 

J’utilise ‘gcc (GCC) 3.4.2 (mingw-special)’ sur un système Windows 7.

Le comportement étrange que je reçois est que tout le contenu n’est pas lu. Par exemple, j’ai un fichier

 05.01.2012 12:28 15.838 hello.exe 

et quand j’essaie de le lire, j’obtiens:

 Read 216 bytes Read 0 bytes 

À ma connaissance, read () devrait continuer à lire jusqu’à la fin du fichier. Alors que rapporte-t-il une fin de fichier (0) la deuxième fois qu’il est appelé?

Peut-être que je manque quelque chose d’évident mais je ne peux pas le voir. J’ai lu ce document et ce document encore et encore et je ne peux pas trouver ce que je fais mal. Quelqu’un at-il des indices?

MODIFIER

Merci pour le conseil! C’est une faute de frappe dans la question (je l’ai corrigée). C’est correct dans le code source.

Je suppose que l’octet 217 EOF (26, 0x1A) – dans les fichiers Windows peut être ouvert en mode “texte” ou “binary”. En mode texte, un 0x1A est interprété comme EOF.

Vous devriez regarder votre mode ouvert – O_BINARY. En PHP, c’est pourquoi vous devez créer le mode “rb” (READ BINARY) et non “R” (“R” qui utilise par défaut READ TEXT).

http://www.mingw.org/wiki/FAQ dit que le drapeau est O_BINARY (près du bas de la page), vous avez donc besoin de

 int fd_in = open(filename, O_RDONLY | O_BINARY, 0644); 

http://cygwin.com/faq.html paragraphe 5.3 vous explique comment gérer cela dans cygwin

void read_file(const char filename)

et plus tard:

int fd_in = open(filename, O_RDONLY, 0x00644);

N’ignorez pas les avertissements du compilateur. Je suis surpris que cela ne soit pas simplement tombé en panne.

Vous voudrez peut-être essayer d’utiliser O_RDONLY | O_BINARY O_RDONLY | O_BINARY ou O_RDONLY | O_NOTRANS O_RDONLY | O_NOTRANS dans l’appel ouvert. En ne spécifiant pas O_BINARY ou O_NOTRANS, le fichier peut être ouvert en mode texte et la lecture s’arrête à la première rencontre du caractère EOF.

J’ai essayé ton code sur ma machine:

  • Windows 7,
  • Cygwin dernière version à ce jour,
  • gcc (GCC) 3.4.4 (cygming special, gdc 0.12, en utilisant dmd 0.125))

et ça a bien fonctionné pour un fichier d’exemple sur ma machine. Le fichier que j’ai lu était cmd.exe dans C:\Windows\System32 et j’ai comparé le nombre total d’octets de votre fonction read_file avec la taille réelle du fichier sur le disque et qu’ils correspondent.

Cela suggère l’une des deux choses suivantes:

  • Il y a quelque chose de spécial avec le fichier que vous ouvrez. Peut-être que c’est dans un étrange état verrouillé et que vous obtenez des erreurs à mi-chemin (jamais entendu parler de cela) ou peut-être que le fichier est corrompu sur le disque (d’autres programmes peuvent-ils y accéder? Essayez de le copier dans un autre dossier)
  • Il y a quelque chose dans votre code qui n’est pas dans la question qui pose problème