バイナリ ファイルを読み込んで、その内容を char 配列に格納しようとしています。この関数は、テキスト ファイルではうまく機能しますが、テキスト以外のファイル (たとえば PNG ファイル) では期待どおりに機能しません。以下は、コードとそれに続く結果です。なにが問題ですか?
コード:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
unsigned int readFile(const char *fileName, char **contents);
int main(int argc, char *argv[])
{
char *contents = 0;
unsigned int length = readFile(argv[1], &contents);
fprintf(stderr, "File length: %d\r\n", length);
fprintf(stderr, "File contents:\r\n%s\r\n", contents);
exit(0);
}
unsigned int readFile(const char *fileName, char **contents)
{
struct stat stbuf;
unsigned int length = 0;
// Open a file descriptor
int fd = open(fileName, O_RDONLY);
// Check that file descriptor was opened
if (fd == -1) {
fprintf(stderr, "Fatal Error: Failed to open the file for fstat (file: %s)!\r\n", fileName);
exit(-1);
}
// Get information from fstat
if (fstat(fd, &stbuf) == -1) {
fprintf(stderr, "Fatal Error: Failed to find file length (file: %s)!\r\n", fileName);
exit(-1);
}
// Store the file length
length = stbuf.st_size;
// Close file descriptor
if (close(fd) == -1) {
fprintf(stderr, "Fatal Error: Failed to close file descriptor (file: %s)!\r\n", fileName);
exit(-1);
}
// Check if the file contains data
if (length > 0) {
// Open the file for reading
FILE *file = fopen(fileName, "rb");
// Check that the file was opened
if (file != NULL) {
freopen(fileName, "rb", file);
// Prepare the contents variable
*contents = 0;
*contents = (char*)calloc(length + 1, sizeof(char));
// Read the file and put it in the contents variable
int lengthRead = fread(*contents, length, 1, file);
// Check for file read error
if (ferror(file)) {
fprintf(stderr, "Fatal Error: Failed to read file (file: %s)!\r\n", fileName);
exit(-1);
}
else if (lengthRead != 1 || strlen(*contents) < length) {
fprintf(stderr, "Fatal Error: File read error (file: %s)!\r\n", fileName);
fprintf(stderr, "Characters expected: %d, Characters read: %d\r\n", length, strlen(*contents));
fprintf(stderr, "Content read:\r\n%s\r\n", *contents);
fprintf(stderr, "Aborting!\r\n", fileName);
// Close file and exit
fclose(file);
exit(-1);
}
// Close binary file
fclose(file);
}
else {
fprintf(stderr, "Fatal Error: Failed to open the file: %s!\r\n", fileName);
exit(-1);
}
}
else {
fprintf(stderr, "Fatal Error: File was empty (file: %s)!\r\n", fileName);
exit(-1);
}
return length;
}
結果:
devious@devious-kubuntu:~/Workspace/test$ ls
test test.c test.png test.txt
devious@devious-kubuntu:~/Workspace/test$ ./test test.txt
File length: 43
File contents:
This is a test file!
With multiple lines!
devious@devious-kubuntu:~/Workspace/test$ ./test test.png
Fatal Error: File read error (file: test.png)!
Characters expected: 50243, Characters read: 8
Content read:
?PNG
¦
Aborting!
ファイルをテキスト モードで開いた場合は、これらの結果が期待できますが、バイナリ モードで開いているため、なぜそうなるのかわかりません。