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
Post a Comment