Read the full content of a binary file

11,462

Solution 1

First of all, you allocate way too much memory. info.st_size * sizeof(char) is enough. You store chars, not pointers.

Then you need to store the file size and use memory functions instead of string functions. A blob of data that contains null bytes is not a string per definition. So it's impossible to get its length except by using the already-known file size.

Solution 2

Here's a modified version of your code. Compare it to yours.

struct stat info;
const char *filename = "just_a_binary_file";
if (stat(filename, &info) != 0) {
    /* error handling */
}   
printf("FILE SIZE: %lu\n", (unsigned long)info.st_size);

char *content = malloc(info.st_size);
if (content == NULL) {
    /* error handling */
}   
FILE *fp = fopen(filename, "rb");
if (fp == NULL) {
    /* error handling */
}
/* Try to read a single block of info.st_size bytes */
size_t blocks_read = fread(content, info.st_size, 1, fp);
if (blocks_read != 1) {
    /* error handling */
}
fclose(fp);

/*
 * If nothing went wrong, content now contains the
 * data read from the file.
 */

printf("DATA LENGTH: %lu\n", (unsigned long)info.st_size);

Note that this approach can still be error-prone in some circumstances. For example, stat() gives you the size of the file at the moment you called stat(). The file's size could have changed between calling stat() and actually reading the file.

Solution 3

You successfully loaded the whole file.

But it contains zero, and zero means end of a (:)) zero terminated string. strlen() won't do you any good.

Solution 4

What you're doing seems ok, the problem lies with strlen... it stops counting when it encounters '\0'. fread will return the number of elements it wrote to content.

Solution 5

It looks to me that you did read the full binary file into content. Binary data is not string data. Strings are NULL terminated. When you examine content in the debugger, yes it looks truncated, but in reality, it is 20481 bytes in size. Look at content in memory and you should see all of it.

Share:
11,462
Fabio Cicerchia
Author by

Fabio Cicerchia

I'm Fabio, a Passionate Solutions Architect and Application Developer with ~20 years of experience. Always enjoying creating quality web applications and web portals using cutting-edge technologies.

Updated on June 30, 2022

Comments

  • Fabio Cicerchia
    Fabio Cicerchia almost 2 years


    I have this piece of C code:

    [...]
    struct stat info;
    char *filename = "just_a_binary_file";
    stat(filename, &info);
    printf("FILE SIZE: %d\n", info.st_size);
    
    char *content = (char *)malloc(info.st_size * sizeof(char *));
    FILE *fp = fopen(filename, "rb");
    fread(content, info.st_size, 1, fp);
    fclose(fp);
    
    printf("STRING LENGTH: %d\n", strlen(content));
    [...]
    

    the output is:

    FILE SIZE: 20481
    STRING LENGTH: 6
    

    the problem is that file contains some Zero-Bytes and when I put the file content into a variable char* the string is truncated at the first occurrence of '\0' (chr(0) precisely).

    The question is how can I get the full binary content into a variable char*?