指的這個問題:Efficient way of reading a file into an std::vector<char>
? 我需要做的事情followig功能:將文件的一部分讀入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福格特
我寫了這兩個簡單的功能:
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
);
你可以使用'reserve'和'back_inserter'和'std :: copy',或者'resize'來獲得一個有效的內存區域來直接填充。 –
爲什麼不把'mmap()'數據放入你的虛擬地址空間?爲什麼你需要一個'矢量'? –
cmaster
@cdhowie我總是這樣做。也許電擊療法最終會打破我的這種習慣。 – WhozCraig