この質問を参照してください:ファイルを?に読み込む効率的な方法 std::vector<char>
次のことを行う関数が必要です。
void readFromFile( std::vector< unsigned char >& buffer,
string filename,
size_t offset, size_t count );
そのため、関数はファイルからオフセットからオフセット + カウントをベクトルに読み取ります。
void readFromFile( std::vector< unsigned char >& buffer,
string filename,
size_t offset, size_t count )
{
// get file size and reallocate the buffer
size_t fsize = filesize( filename );
buffer.reserve( buffer.size() + size );
// open the file
ifstream file( filename );
// first way
file.seekg( offset );
file.read( ???? )
// second way
istreambuf_iterator< unsigned char > from( file );
istreambuf_iterator< unsigned char > eof;
advance( from, offset );
copy( from, eof, back_inserter( buffer );
}
最初の方法では、ファイルを一度に読み取る方法がわかりません。2 番目の方法では、バイトごとに読み取るため、読み取り操作が非常に遅くなります。
より良い代替手段はありますか?
編集
@Ben Voigtに感謝
この2つの単純な関数を書きました:
inline std::streamsize filesize( const std::string& filename )
{
std::ifstream in( filename, std::ifstream::in | std::ifstream::binary );
if ( !in ) throw std::invalid_argument
{
"filesize error: invalid filename"
};
in.seekg( 0, std::ifstream::end );
return in.tellg();
// here the file is closed. so no need to restore the get pointer
}
inline std::streamsize filesize( std::ifstream& file )
{
file.seekg( 0, std::ifstream::end );
const auto size = file.tellg();
file.seekg( 0 ); // restore the get pointer
return size;
}
template< typename RAIter >
inline void read_file( std::istream& file,
RAIter first, RAIter last,
std::streamsize offset = 0
)
{
const auto size = last - first;
file.seekg( offset, std::ifstream::beg );
file.read( reinterpret_cast< char* >( &*first ), size );
}
template<>
inline void read_file( std::istream& file,
unsigned char* first, unsigned char* last,
std::streamsize offset /*= 0 no default argument in template spacalization. */
)
{
const auto size = last - first;
file.seekg( offset, std::ifstream::beg );
file.read( reinterpret_cast< char* >( first ), size );
}
そのため、関数は簡単になりました。
vector< unsigned char > buffer;
// do something with buffer
const string filename{ "blabla" };
const auto size = filesize( filename );
// resize the buffer
auto const OLD_LEN = buffer.size();
buffer.resize( OLD_LEN + size );
size_t startOffset = 0; // from where to star reading from file
size_t cont = size; // how manny bytes read from file
// read filename from startOffset to startOffset + count, appendeing in buffer
ifstream file( filename );
read_file( file,
buffer.data() + OLD_LEN,
buffer.data() + OLD_LEN + count,
startOffset
);