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