将文件的一部分读取到 std::vector 中的有效方法<char>?
Efficient way of reading part of a file into an std::vector<char>?
参考这个问题:将文件读取到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 );
}
第一种方法是,我不知道如何立即读取文件。在第二种方式中,读取操作相当慢,因为我是逐字节读取的。
有更好的替代方案吗?
编辑
感谢@Ben Voigt
我写了两个简单的函数:
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
);
auto old_end = buffer.size();
buffer.resize( old_end + blocksize );
//...
file.read( &buffer[old_end], blocksize );
auto actual_size = file.gcount;
if (actual_size < blocksize) buffer.resize(old_end + actual_size);
这里有一种从文件中获取字符数组的快速高效的方法。
char * arr;
int len;
// Function that opens a file, needing the file name
void openFile(const char* fileName)
{
ifstream file(fileName, ios::in);
if(!file.is_open()) return;
file.seekg(0, file.end);
// Get the length of the file
len = file.tellg();
file.seekg(0, file.beg);
arr = new char[len];
file.read(arr, len);
file.close();
}
之后,您可以将char数组推送到一个向量中。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 没有为自己的结构调用列表推回方法
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- C / CUDA中的模板方法是3个角括号(&lt;&lt;&lt;)
- 超载&LT的正确方法;操作员