2009-10-27 120 views
6

是否有更好的方法來確定一個std的長度:: istream的比下面確定std :: istream長度的更好方法是什麼?

std::istream* pcStream = GetSomeStream(); 
pcStream->seekg(0, ios::end); 
unsigned int uiLength = pcStream->tellg(); 

它只是似乎真的浪費不得不尋求流的末尾,然後設法回到原來的位置,特別是如果流可能是在某些慢速媒體(如CD或DVD)上的文件。

+0

爲什麼你需要這個長度? – sbi 2009-10-27 15:09:13

+0

我使用的API需要我傳遞的數據的大小。它使用原始字符緩衝區,並繼續處理它直到達到緩衝區的末尾。 – FlintZA 2009-10-29 09:18:13

+0

你可以在文件上使用'stat()'。然而,在閱讀內容之前,它並沒有比尋找最後的東西和在開始時尋找回來更快......這就是文件描述符的實現方式。當然,'stat()'不是C++,它需要一個文件名... – 2017-03-11 02:28:37

回答

7

「最佳」的方法是避免需要長度:)

  • 並非所有的流是可查找(例如,設想在一個網絡套接字的istream)
  • 從所以tellg返回類型()不一定是數字(唯一的要求是它可以傳遞迴seekg()返回到相同的位置)
  • 即使它是數字,它也不一定是字節數。例如,它可能是一個「神奇」的價值,意思是「底」
  • 對於fstreams,如情況和換行轉換問題可以搞砸
+0

我確實意識到期望長度總是可用是有點限制使用的流類型,謝天謝地,我不太可能除了ifstream和我自己的memstream和zipstream實現之外,還可以使用其他任何東西。 – FlintZA 2009-10-29 09:19:39

+0

它看起來像tellg()的返回類型始終是數字,基於std :: streampos的約束(http://stackoverflow.com/a/24437482/145173)。 – 2015-09-19 16:21:41

-1

你有沒有考慮使用IStream的跟蹤大小:: gcount()?

+1

我需要分配數據將被複制到的緩衝區的大小 - 我想我可以分配一個初始數量,然後重新分配,但我有點擔心碎片(在有限的mem環境中工作)。 – FlintZA 2009-10-29 10:21:12

-1

有某種類型的流通過調用tellg()無法獲得長度。 如果是,tellg()可能會返回-1

您可以通過準備足夠大小的緩衝區來獲取流的長度。 我發現如何通過查看stream::read函數來獲得長度。

const int DATA_SIZE = 1024 * 512; 
char buf[DATA_SIZE]; // 1024 * 512 is enough! 
std::istream& is = GetSomeStream(); 
int Len = is.rdbuf()->sgetn(buf, DATA_SIZE); 

以上,Lenistream真實數據的大小。

相關問題