2011-01-21 38 views
34

我想避免不必要的副本。我的目標線沿線的東西:將文件讀入std :: vector的有效方法<char>?

std::ifstream testFile("testfile", "rb"); 
std::vector<char> fileContents; 
int fileSize = getFileSize(testFile); 
fileContents.reserve(fileSize); 
testFile.read(&fileContents[0], fileSize); 

(不工作,因爲reserve實際上不插入任何物件載體,所以我不能訪問[0])。

當然,std::vector<char> fileContents(fileSize)作品,但初始化所有元素的開銷(fileSize可能相當大)。相同的resize()

這個問題並不那麼重要,這個開銷會是多麼重要。相反,我只是想知道是否有另一種方式。

+1

如果您想要避免`push_back`所需的重新分配成本_and_您想要避免使用`resize`所需的緩衝區清零的成本,請根本不要使用`std :: vector`:use a `boost :: scoped_array`或類似的東西。 – 2011-01-21 17:32:04

回答

54

規範形式是這樣的:

#include<iterator> 
// ... 

std::ifstream testFile("testfile", std::ios::binary); 
std::vector<char> fileContents((std::istreambuf_iterator<char>(testFile)), 
           std::istreambuf_iterator<char>()); 

如果你擔心再分配然後在矢量預留空間:

#include<iterator> 
// ... 

std::ifstream testFile("testfile", std::ios::binary); 
std::vector<char> fileContents; 
fileContents.reserve(fileSize); 
fileContents.assign(std::istreambuf_iterator<char>(testFile), 
        std::istreambuf_iterator<char>()); 
+0

這個矢量在增長的時候不會重新分配嗎? (由於迭代器可能不支持減法,因此構造函數無法預先確定大小。) – Thomas 2011-01-21 17:22:46

0

如果我理解正確,您想要讀取每個元素,但不想將其全部載入fileContents,那麼正確? 我個人不認爲這會造成不必要的副本,因爲多次打開文件會降低性能。在這種情況下,讀入一個fileContents向量是一個合理的解決方案。

+0

我並不是故意投票,但它被鎖定。如果您編輯答案,我可以/將刪除投票。 – ditkin 2015-01-21 17:25:44

5

如果你想真正的零拷貝讀取,也就是說,要消除從內核到用戶空間的複製,只需將該文件映射到內存中即可。編寫你自己的映射文件包裝或使用boost::interprocess

相關問題