2012-01-21 75 views
0

對於一個項目我工作的加載/在文件中存儲數據,我做了實現,因爲其中一些它擁有比其他文件IO庫的特徵iostream庫,決定。一個這樣的特徵是能夠使用派生fstream或stringstream類來允許從文件或存儲器中已經存在的地方加載數據。雖然到目前爲止,還有一次重大倒退,但我一直在收集有關它的信息時遇到了麻煩。C++截斷對iostream類

在POSIX庫提供的功能類似,我一直在尋找的截形或ftruncate功能的一些執行情況。對於串流來說,這很容易,只需將相關字符串以不同的大小重新構建,就可以傳回流中。對於fstream,實際上,我還沒有找到任何方法來做這件事,因爲我甚至找不到一種方法來將該句柄從該類中拉出。雖然給我一個fstream問題的解決方案會很好,但對這個問題的更好的解決方案將不得不是友好的。因爲每個流類的每個用法都通過我的程序中的一個iostream,所以通過基類截斷它們會比在每次想要更改整個大小時必須找出哪個類正在控制流更容易。

另外,如果有人可以點我實現所有這些功能我要找的,是溫和易於更換的iostream庫,這將是一個很好的解決方案,以及。

編輯:爲了澄清,我使用的是iostream類更有可能只是僅使用stringstream的和fstream的類。實際上,只有文件本身需要被截斷到某個特定點,我只是尋找一種更簡單的方法來處理這個問題,而不需要我知道流的哪種類型的流連接。正如答案所建議的那樣,我將研究一種在fstream旁邊使用ftruncate的方法,並且只處理兩個特定的情況,因爲我的程序的最終用戶不應該看到流類。

+0

你的目標是什麼?你想限制可以寫入流的數量嗎?這可以通過過濾'std :: streambuf'輕鬆完成。在事實之後截斷取決於寫入數據的位置,顯然,可以爲所有流完成。例如,如果您已將字符寫入控制檯或套接字,則無法讓它們返回。 –

回答

0

您不能截斷到位的iostream。您必須將現有流的前N個字節複製到新的字節。這可以用下面的streambuf對象的sgetn()sputn()方法,您可以通過iostream::rdbuf()得到完成。

但是,該過程可能是I/O密集型的。正如你所提到的,使用特殊情況來操縱std::string或致電ftruncate可能會更好。

如果你想成爲真的侵略性,您可以創建自定義std::streambuf派生類保持一個指向已存在rdbuf對象流,只產生artifiicial結束之前讀取到一定點-文件。這將看起來像一個更短的I/O序列的用戶,但實際上不會釋放內存或文件系統空間。 (目前還不清楚這對你是否重要。)

+0

請注意,您應該**不刪除從rdbuf()返回的結果:流緩衝區應該由派生流類擁有(例如'std :: fstream'通常嵌入'std :: filebuf'到對象中)或由一個外部實體使用'rdbuf()'安裝了一個流緩衝區。無論哪種情況,調用'rdbuf()'都不會將所有權轉讓給您! –

+0

@DietmarKühl:對,很抱歉,修正。這個解決方案比我意識到的更加駭人聽聞...... iostreams是一團糟。 – Potatoswatter