Ημερήσια αρχεία: 23 Δεκεμβρίου 2016


C/C++: Full example of reading a whole binary file to buffer 1

The following example will read a binary in full and store it to a buffer in memory.

[download id=”2487″]

We used the custom structure binary_data_t to store the data information.
This structure stores the pointer to the data and their size.

struct binary_data_t {
  long size;
  void *data;
};

In main.cpp we performed three tests

  1. Reading a file that exists and is not empty
  2. Reading a non-existing file
  3. Reading an empty file

[download id=”2487″]

file_helpers.h


#ifndef GM_S_LITTLE_HELPERS_FILE_HELPERS_H
#define GM_S_LITTLE_HELPERS_FILE_HELPERS_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct binary_data_t binary_data_t;
struct binary_data_t {
  long size;
  void *data;
};

binary_data_t * read_file(const char *filename);

#ifdef __cplusplus
}
#endif

#endif //GM_S_LITTLE_HELPERS_FILE_HELPERS_H

file_helpers.c


#include <stdio.h>
#include <malloc.h>
#include "file_helpers.h"


//Returns a binary_data_t structure if reading the file was OK.
//In case of an error it always returns NULL.
binary_data_t *read_file(const char *filename) {

  //Allocated our binary data structure
  binary_data_t *binary_data = malloc(sizeof(binary_data_t));
  if (binary_data != NULL) {

    binary_data->size = 0;
    void *buffer = NULL;
    long position;
    //Open the file for reading in binary mode
    FILE *fIn = fopen(filename, "rb");

    if (fIn != NULL) {
      //Go to the end of the file
      const int fseek_end_value = fseek(fIn, 0, SEEK_END);
      if (fseek_end_value != -1) {

        //Get the current position in the file (in bytes)
        position = ftell(fIn);
        if (position != -1) {

          //Go back to the beginning of the file
          const int fseek_set_value = fseek(fIn, 0, SEEK_SET);
          if (fseek_set_value != -1) {

            //Allocate enough space to read the whole file
            buffer = malloc(position);
            if (buffer != NULL) {

              //Read the whole file to buffer
              const long size = fread(buffer, 1, position, fIn);

              if (size == position) {
                binary_data->size = position;
                binary_data->data = buffer;

                fclose(fIn);
                return binary_data;
              }
              free(buffer);
            }
          }
        }
      }
      fclose(fIn);
    }
    free(binary_data);
  }
  return NULL;
}

main.cpp


#include <iostream>
#include "file_helpers.h"

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

  //Testing a non-zero sized file
  //read_file() will return a binary_data_t where size will be non zero
  binary_data_t *binary_data_non_zero = read_file(argv[0]);
  //Testing for a non-existing file
  //read_file() will return a NULL pointer
  binary_data_t *binary_data_not_existing = read_file("some file that does not exist...");
  const char * filename = "/tmp/some_empty_file";
  //Creating an empty file
  FILE * fout = fopen(filename, "w");
  fclose(fout);
  //Testing for an empty file
  //read_file() will return a binary_data_t where size will be zero
  binary_data_t *binary_data_empty = read_file(filename);

  return EXIT_SUCCESS;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(GM_s_Little_Helpers)

set(CMAKE_CXX_STANDARD 11)

include_directories(${CMAKE_CURRENT_SOURCE_DIR})

set(SOURCE_FILES main.cpp file_helpers.c file_helpers.h)
add_executable(GM_s_Little_Helpers ${SOURCE_FILES})

target_link_libraries(GM_s_Little_Helpers)

[download id=”2487″]