C Language - Read binary file in its full size

Asked

Viewed 48 times

-2

I’m developing a software that needs to read a binary file and display its contents. Currently it is displaying the content correctly, but I do not know how to do the loop read the total content from the file to the end, as I currently defined a value of 512, but I wish to use the sizeof(), to collect the full size of bytes inside the file. How do I do it ?

Output and current writing on terminal:

00 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 f0 00 f0 00 00 ff db 00 43 00 06 04 05 06 05 04 06 06 05 06 07 07 06 08 0a 10 0a 0a 09 09 0a 14 0e 0f 0c 10 17 14 18 18 17 14 16

My current code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

    if (argc < 2)
    {
        printf("Usage: Please insert the file name\n");
        return 1;
    }
    
    else
    {
        long acumulador;
        long buffer[512];
        FILE *file = fopen(argv[1], "r");
        
        //Cannot open file
        if (file == NULL)
        {
            printf("Cannot open file \n");
            exit(0);
        }
        //The file was opened
        else
        {
            //Read the content
            while(!feof(file))
            {
                int i = 0;
                
                for(i = 0; i < 512; i++)
                {
                    fread(&acumulador, 1, 1, file);
                    buffer[i] = acumulador;
                    
                    printf("%02x", buffer[i]);
                    printf(" ");
                }
      
            }
        }
    }       
}

2 answers

1


sizeof() is an operator, see documentation.

The common way to identify the size of a file is to use stat() or use fseek() and ftell().

Using fseek() and ftell()

The excerpt below shows the common: open the file, move the cursor to the end and see where it is, which is the file size.

FILE* F = fopen(arquivo, "r");
if (F == NULL) return -1;
long posicao = ftell(F);
printf("Na abertura: \"cursor\" de \"%s\" em %ld\n",
    arquivo, posicao);
fseek(F, 0, SEEK_END);
posicao = ftell(F);
printf("Posicionado no fim: \"cursor\" em %ld\n",
    posicao);

Using stat()

stat() fills a structure with information about the file, as in:

printf("Usando stat() para obter informacoes do arquivo:\n");
struct stat info;
if (stat(arquivo, &info) == -1)
{
    perror("Erro em lstat");
    exit(1);
}
printf("Tipo do arquivo \"%s\": ", arquivo);
printf("Tamanho: %ld bytes\n", (intmax_t)info.st_size);
printf("Última mudança de status em %s", ctime(&info.st_ctime));
printf("Último acesso em %s", ctime(&info.st_atime));
printf("Última modificação em %s", ctime(&info.st_mtime));

that shows something like:

Na abertura: "cursor" de "fst-0829.exe" em 0
Posicionado no fim: "cursor" em 54784
Usando stat() para obter informações do arquivo:
Tipo do arquivo "fst-0829.exe": Tamanho: 54784 bytes
Última mudança de status em Mon Aug 30 12:35:13 2021
Último acesso em Mon Aug 30 13:05:34 2021
Última modificação em Mon Aug 30 13:05:23 2021

On my computer now, on Windows:

struct stat
{
    _dev_t         st_dev;
    _ino_t         st_ino;
    unsigned short st_mode;
    short          st_nlink;
    short          st_uid;
    short          st_gid;
    _dev_t         st_rdev;
    _off_t         st_size;
    time_t         st_atime;
    time_t         st_mtime;
    time_t         st_ctime;
};

An example in C

This program takes the name of the file in the command line and shows both ways:

#include <locale.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>

int  testa_arquivo(const char*);
void uso();

int main(int argc, char** argv)
{
    setlocale(LC_ALL, "pt-br");
    if (argc < 2) uso();
    testa_arquivo(argv[1]);
    return 0;
}

int testa_arquivo(const char* arquivo)
{
    FILE* F = fopen(arquivo, "r");
    if (F == NULL) return -1;
    long posicao = ftell(F);
    printf("Na abertura: \"cursor\" de \"%s\" em %ld\n",
        arquivo, posicao);
    fseek(F, 0, SEEK_END);
    posicao = ftell(F);
    printf("Posicionado no fim: \"cursor\" em %ld\n",
        posicao);
    fseek(F, 0, SEEK_SET); // volta pro inicio

    printf("Usando stat() para obter informacoes do arquivo:\n");
    struct stat info;
    if (stat(arquivo, &info) == -1)
    {
        perror("Erro em lstat");
        exit(1);
    }
    printf("Tipo do arquivo \"%s\": ", arquivo);
    printf("Tamanho: %ld bytes\n", (intmax_t)info.st_size);
    printf("Última mudança de status em %s", ctime(&info.st_ctime));
    printf("Último acesso em %s", ctime(&info.st_atime));
    printf("Última modificação em %s", ctime(&info.st_mtime));
    fclose(F);
    return 0;
}

void uso()
{  // o classico
    printf("Use: \"programa arquivo\"\n");
    exit(0);
}

Exit:

C:> ./fst-0829 fst-0829.exe
Na abertura: "cursor" de "fst-0829.exe" em 0
Posicionado no fim: "cursor" em 54784
Usando stat() para obter informacoes do arquivo:
Tipo do arquivo "fst-0829.exe": Tamanho: 54784 bytes
Última mudança de status em Mon Aug 30 12:35:13 2021
Último acesso em Mon Aug 30 13:05:34 2021
Última modificação em Mon Aug 30 13:05:23 2021
C:> 

0

sizeof() is not appropriate for this task. sizeof() is a pseudo-function that calculates the size of a type at compile time.

To find out the file size, you need to test the fread() return value. In case, as you are using fread() to read 1 byte at a time, just test if the return is <= 0. If yes, hit the end.

Another option would be to discover the file size a priori, before starting to read it, using the functions fseek(), ftell() and Rewind().

  • OK thank you very much

  • sizeof() is an operator

Browser other questions tagged

You are not signed in. Login or sign up in order to post.