Solución:
Solo quiero mencionar que existe una forma estándar de leer un archivo binario en un búfer.
Utilizando <cstdio>
:
char buffer[BUFFERSIZE];
FILE * filp = fopen("filename.bin", "rb");
int bytes_read = fread(buffer, sizeof(char), BUFFERSIZE, filp);
Utilizando <fstream>
:
std::ifstream fin("filename.bin", ios::in | ios::binary );
fin.read(buffer, BUFFERSIZE);
Lo que haga después con el búfer depende de usted, por supuesto.
Editar: ejemplo completo usando <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 %sn", 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;
}
El problema es definitivamente la escritura de su búfer, porque lee un byte a la vez.
Si conoce la longitud de los datos en su búfer, podría forzar a cout a continuar:
char *bf = "Hello world";
cout << bf << endl;
cout << string(bf, 12) << endl;
Esto debería dar el siguiente resultado:
Hello
Hello world
Sin embargo, esta es una solución alternativa, ya que se prevé que cout genere datos imprimibles. Tenga en cuenta que la salida de caracteres no imprimibles como ‘ 0’ depende del sistema.
Soluciones alternativas:
Pero si manipula datos binarios, debe definir estructuras de datos e impresión ad-hoc. Aquí algunas sugerencias, con un breve borrador de los principios generales:
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)); }
} ;
Entonces podría sobrecargar la función del operador de salida:
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;
}
Y podrías usarlo así:
char *bf = "Hello 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);
}
y luego
auto vec = read_binary_file(filename);
auto src = (char*) new char[vec.size()];
std::copy(vec.begin(), vec.end(), src);