Lately I've been asked to write a function that reads the binary file into the std::vector<BYTE>
where BYTE
is an unsigned char
. Quite quickly I came with something like this:
#include <fstream>
#include <vector>
typedef unsigned char BYTE;
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::streampos fileSize;
std::ifstream file(filename, std::ios::binary);
// get its size:
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// read the data:
std::vector<BYTE> fileData(fileSize);
file.read((char*) &fileData[0], fileSize);
return fileData;
}
which seems to be unnecessarily complicated and the explicit cast to char*
that I was forced to use while calling file.read
doesn't make me feel any better about it.
Another option is to use std::istreambuf_iterator
:
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::ifstream file(filename, std::ios::binary);
// read the data:
return std::vector<BYTE>((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
}
which is pretty simple and short, but still I have to use the std::istreambuf_iterator<char>
even when I'm reading into std::vector<unsigned char>
.
The last option that seems to be perfectly straightforward is to use std::basic_ifstream<BYTE>
, which kinda expresses it explicitly that "I want an input file stream and I want to use it to read BYTE
s":
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::basic_ifstream<BYTE> file(filename, std::ios::binary);
// read the data:
return std::vector<BYTE>((std::istreambuf_iterator<BYTE>(file)),
std::istreambuf_iterator<BYTE>());
}
but I'm not sure whether basic_ifstream
is an appropriate choice in this case.
What is the best way of reading a binary file into the vector
? I'd also like to know what's happening "behind the scene" and what are the possible problems I might encounter (apart from stream not being opened properly which might be avoided by simple is_open
check).
Is there any good reason why one would prefer to use std::istreambuf_iterator
here?
(the only advantage that I can see is simplicity)