C++: Store Read Binary File Into Buffer


Answer :

I just want to mention that there is a standard way to read from a binary file into a buffer.

Using <cstdio>:

char buffer[BUFFERSIZE];  FILE * filp = fopen("filename.bin", "rb");  int bytes_read = fread(buffer, sizeof(char), BUFFERSIZE, filp); 

Using <fstream>:

std::ifstream fin("filename.bin", ios::in | ios::binary ); fin.read(buffer, BUFFERSIZE); 

What you do with the buffer afterwards is all up to you of course.

Edit: Full example using <cstdio>

#include <cstdio>  const int BUFFERSIZE = 4096;      int main() {     const char * fname = "filename.bin";     FILE* filp = fopen(fname, "rb" );     if (!filp) { printf("Error: could not open file %s\n", fname); return -1; }      char * buffer = new char[BUFFERSIZE];     while ( (int bytes = fread(buffer, sizeof(char), BUFFERSIZE, filp)) > 0 ) {         // Do something with the bytes, first elements of buffer.         // For example, reversing the data and forget about it afterwards!         for (char *beg = buffer, *end=buffer + bytes; beg < end; beg++, end-- ) {            swap(*beg, *end);         }     }      // Done and close.     fclose(filp);      return 0; } 

The problem is definitievely the writing of your buffer, because you read a byte at a time.

If you know the length of the data in your buffer, you could force cout to go on:

char *bf = "Hello\0 world";  cout << bf << endl; cout << string(bf, 12) << endl; 

This should give the following output:

Hello Hello  world 

However this is a workaround, as cout is foreseent to output printable data. Be aware that the output of non printable chars such as '\0' is system dependent.

Alternative solutions:

But if you manipulate binary data, you should define ad-hoc data structures and printing. Here some hints, with a quick draft for the general principles:

struct Mybuff {   // special strtucture to manage buffers of binary data     static const int maxsz = 512;      int size;     char buffer[maxsz];      void set(char *src, int sz)  // binary copy of data of a given length     { size = sz; memcpy(buffer, src, max(sz, maxsz)); } } ;  

Then you could overload the output operator function:

ostream& operator<< (ostream& os, Mybuff &b) {     for (int i = 0; i < b.size; i++)          os.put(isprint(b.buffer[i]) ? b.buffer[i]:'*');  // non printables replaced with *     return os; } 

ANd you could use it like this:

char *bf = "Hello\0 world";  Mybuff my;  my.set(bf, 13);   // physical copy of memory cout << my << endl;   // special output  

static std::vector<unsigned char> read_binary_file (const std::string filename) {     // binary mode is only for switching off newline translation     std::ifstream file(filename, std::ios::binary);     file.unsetf(std::ios::skipws);      std::streampos file_size;     file.seekg(0, std::ios::end);     file_size = file.tellg();     file.seekg(0, std::ios::beg);      std::vector<unsigned char> vec(file_size);     vec.insert(vec.begin(),                std::istream_iterator<unsigned char>(file),                std::istream_iterator<unsigned char>());     return (vec); } 

and then

auto vec = read_binary_file(filename); auto src = (char*) new char[vec.size()]; std::copy(vec.begin(), vec.end(), src); 

Comments

Popular posts from this blog

Converting A String To Int In Groovy

"Cannot Create Cache Directory /home//.composer/cache/repo/https---packagist.org/, Or Directory Is Not Writable. Proceeding Without Cache"

Android How Can I Convert A String To A Editable