Нещодавно мене попросили написати функцію, яка зчитує двійковий файл у 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
тут?
(Єдина перевага, яку я бачу, - це простота)