2010-10-07 89 views
5

std::istream有原型istream& read (char* s, streamsize n)實際讀取的字節數應通過調用istream::gcount(),也istream的有效性可以從ios::good知道來得到。瞭解的std :: istream的設計::閱讀

我正在討論另一個流類的實現,我試圖和我的一個同事一起寫,我在說我可能會遵循這個設計;但他表示,不要每次都有用戶致電gcount,否則可能會看到像istream& read (char* s, streamsize n, size_t &bytes_read)這樣的原型,所以它會在一次通話中結束,前者更笨拙。我無法防守std的設計選擇。 istream::read背後的真正理由是什麼?

+0

你的意思是'size_t&bytes_written'嗎?而且,它應該是'streamsize&bytes_written'(或者'chars_read')。 – 2010-10-07 14:22:39

+0

@詹姆斯:是的,謝謝!字節和字符是同義詞_here_,因爲'sizeof'是相同的:) – legends2k 2010-10-07 14:43:48

回答

4

我認爲這是因爲C++通常不會強制所有人都不需要的接口。如果您需要read接受某些人不關心的參數,那麼它會導致額外的編碼工作(聲明一個額外的int作爲參數傳遞)。無論客戶端是否在意,它也總是保存讀取的字節數(某些客戶端可能會在意eof/fail位指示的讀取失敗)。

使用單獨的方法,您可以爲可能需要或不需要的不同信息的接口分離接口。

0

std::istream有原型 istream& read (char* s, streamsize n)實際讀取的字節數 應通過調用 istream::gcount(),還有效性的istream的 可以從 ios::good知道來得到。

istream::read(char* s, streamsize n)讀取數據的大小n的未格式化的塊(沒有NULL終止)成s陣列。儘管s是指向char的指針,但您可以使用istream::read來讀取二進制數據。例如,你可以有一個istream持有雙打(假設字節順序是正確的)數組的值:

unsigned int count; 
input.read(reinterpret_cast<char*>(&count), sizeof(count)); 
double* data = new double[count]; 

for (unsigned int i = 0; i < count; ++i) 
    input.read(reinterpret_cast<char*>(data[i]), sizeof(double)); 

istream::gcount()返回最後istream::read通話讀取的字節數。在這種情況下,我們看到count的大小可能與double的大小不同,因此我們將無法使用istream::gcount()指定data數組中第一個元素的大小。

+0

@CashCow對'istream :: read'的侷限性有正確的解決方案。我無法贊成,因爲我沒有至少15點的聲望(我仍然是Stack Overflow n00b)。 – 2010-10-11 15:58:12

+0

我的實際問題是,爲什麼我們需要調用'gcount';相反,爲什麼沒有它像調用者可以傳遞一個refernce變量,它將由'read'設置爲實際讀取的字節數(可以小於或等於'streamsize n'),而不是調用者調用gcount每次。 – legends2k 2010-10-13 13:14:21

+0

用'istream :: readsome'解釋@CashCow讀取的字節數似乎更可取。正如@Mark B所解釋的,它避免了必須聲明一個額外的int來通過引用傳遞。另一種選擇是將指針傳遞給默認爲NULL的變量,該變量可用於忽略讀取的實際字節數:'istream&read(char * s,streamsize n,streamsize * bytesRead = NULL)'。但是,我不知道它是否會比'istream :: readsome'提供顯着的優勢。 – 2010-10-13 13:42:02

2

嘗試readsome命令來代替,

streamsize readsome (char* buf, streamsize num); 

BUF是你的緩衝區和num是要讀取的字節數,最多的當然是在你的緩衝區可用的字節,數。

返回值是實際讀取的字節數。

要讀取文件的最後,你可以循環:

char buf[BUF_SIZE] 
streamsize bytesRead; 
do 
{ 
    bytesRead = instr.readsome(buf, BUF_SIZE); 
    // do stuff with the bytes you read, if any 
} while (bytesRead == BUF_SIZE); 
0

在回答原來的問題,有錯誤檢查調用的是一種流行的編程風格當C是年輕的,但它很快就熄滅了時尚的後。發生的事情是那些沒有錯誤的小事情,但是在一段時間之後,它們幾乎總是存在一些劣勢,直到它們被社區叫出來並被貼上壞標籤。這個代碼有一個不幸之處,那就是在廣泛討論這個小反模式之前寫了這個代碼。

爲了迴應Cash Cow的解決方案,我認爲存在一個錯誤。如果您在IO上等待並且有足夠的字符來部分填充緩衝區,那麼該函數將返回並且while循環將在文件被完全讀取之前結束。所以如果在直接原始IO上寫入,他的解決方案可能會正確運行,但是會在緩衝IO上運行失敗。

當然,正確的解決方案是在設置EOF標誌時結束while循環。目前我還不確定什麼時候最好的反應是什麼時候設置了badbit,但你也應該處理這種情況。

雖然,我會同意readsome是一個體面的替代閱讀。

編輯: 有時讀取不可用(一些VC++版本)。在這種情況下,讀取不可用。