How to Read Binary File in C

Jinku Hu Feb 02, 2024
  1. Use the fread Function to Read Binary File in C
  2. Use the read Function to Read Binary File in C
How to Read Binary File in C

This article will demonstrate multiple methods of how to read a binary file in C.

Use the fread Function to Read Binary File in C

fread is part of the C standard library input/output facilities, and it can be utilized to read binary data from regular files. The C standard library implements a user-buffered I/O along with a platform-independent solution to handle reading/writing binary file data. Standard I/O functions operate on file pointers instead of file descriptors. FILE* streams are retrieved by the fopen function, which takes the file path as the string constant and the mode to open them. The mode of the file specifies whether to open a file for reading, writing or appending. Mind though, each mode string can include the letter b to explicitly specify binary file mode, which can be interpreted by some non-UNIX systems that treat text and binary files differently.

After the fopen returns the file pointer, we can call the fread function to read binary stream. fread takes four arguments, the first of which is the void pointer to the location where the read bytes should be stored. The next two arguments specify the size and number of the data items that need to be read from the given file. Finally, the fourth argument to the function is the FILE pointer from which the data should be read. In the following example, we open and write some arbitrary bytes to the file named input.txt. Then, we close the file and open it again for reading.

#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

const uint8_t data[] = {0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72,
                        0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
                        0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x77,
                        0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x74,
                        0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65};

const char* filename = "input.txt";

int main(void) {
  FILE* output_file = fopen(filename, "wb+");
  if (!output_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  fwrite(data, 1, sizeof data, output_file);
  printf("Done Writing!\n");
  fclose(output_file);

  FILE* in_file = fopen(filename, "rb");
  if (!in_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* file_contents = malloc(sb.st_size);
  fread(file_contents, sb.st_size, 1, in_file);

  printf("read data: %s\n", file_contents);
  fclose(in_file);

  free(file_contents);
  exit(EXIT_SUCCESS);
}

Output:

Done Writing!
read data: Temporary string to be written to file

Use the read Function to Read Binary File in C

Alternatively, we can use the read function that is essentially a system call underneath the hood. Notice that read works on file descriptors; thus the file should be opened with the open system call. It takes additional two arguments denoting the void pointer where the read data will be stored and the number bytes to be read from the file. Note that we are reading the full contents of the file and allocating the memory for it dynamically using the malloc function. stat system call is utilized to find the file size.

#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

const uint8_t data[] = {0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72,
                        0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
                        0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x77,
                        0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x74,
                        0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65};

const char* filename = "input.txt";

int main(void) {
  FILE* output_file = fopen(filename, "wb+");
  if (!output_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  fwrite(data, 1, sizeof data, output_file);
  printf("Done Writing!\n");
  fclose(output_file);

  int fd = open(filename, O_RDONLY);
  if (fd == -1) {
    perror("open\n");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* file_contents = malloc(sb.st_size);
  read(fd, file_contents, sb.st_size);

  printf("read data: %s\n", file_contents);
  close(fd);

  free(file_contents);

  exit(EXIT_SUCCESS);
}

Output:

Done Writing!
read data: Temporary string to be written to file
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C File