В последнее время мне было предложено написать функцию, которая читает двоичный файл в std::vector<BYTE>
, где BYTE
- unsigned char
. Довольно быстро я пришел с чем-то вроде этого:
#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;
}
который кажется излишне сложным, и явное приведение к char*
, которое я вынужден использовать при вызове file.read
, не заставляет меня чувствовать себя лучше.
Другой вариант - использовать 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>());
}
который довольно прост и короток, но все же мне нужно использовать std::istreambuf_iterator<char>
, даже когда я читаю в std::vector<unsigned char>
.
Последний вариант, который кажется совершенно простым, заключается в использовании std::basic_ifstream<BYTE>
, который явно выражает это явно: "Я хочу поток входных файлов, и я хочу используйте его для чтения 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>());
}
но я не уверен, что basic_ifstream
является подходящим выбором в этом случае.
Каков наилучший способ чтения двоичного файла в vector
? Я также хотел бы знать, что происходит "за сценой" и каковы возможные проблемы, с которыми я мог столкнуться (кроме потока, который не открывается должным образом, чего можно избежать простым is_open
).
Есть ли веская причина, почему вы предпочитаете использовать std::istreambuf_iterator
здесь?
(единственное преимущество, которое я вижу, это простота)