還有更給它不僅僅是「的文件可能不適合在內存」。爲Stream.Read
合同明確說:
這種方法的
實現從 電流流讀取 最大的數個字節,並將它們存儲在緩衝區 開始偏移量。 流內的當前位置是 先讀取的字節數;然而,如果發生異常,流 內的當前位置保持不變。實現 返回讀取的字節數。僅當 位置當前位於 流的末尾時, 返回值爲零。在 沒有數據可用的情況下,該實現將 阻塞,直到可以讀取至少一個字節的數據 。僅當 流 中沒有更多數據且預期不再有更多數據(例如 關閉的套接字或文件結尾)時,只讀取返回0。即使未到達流的結尾 , 實現也可以自由返回比請求少的 字節。
請注意最後一句 - 您不能依靠一個電話來Stream.Read
來讀取所有內容。
爲FileStream.Read
該文檔具有類似的警告:
讀入 緩衝區的字節總數。如果 字節當前不是 可用,則可能小於 所請求的字節數,如果達到 流的末尾,則可能爲零。
對於本地文件系統,我不確定這是否真的會發生 - 但它可以爲網絡掛載的文件。你想讓你的應用變得脆弱嗎?
在一個循環看書做事可靠的方法。我個人更喜歡不要求流支持Length
財產,或者:
public static byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[8192];
using (MemoryStream tmpStream = new MemoryStream())
{
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
tmpStream.Write(buffer, 0, bytesRead);
}
return tmpStream.ToArray();
}
}
當長度爲事先知道,但它是很好的和簡單的稍微低效率的。您只需實施一次,將其放入實用程序庫中,並在需要時隨時撥打電話。如果您確實介意效率損失,則可以使用CanSeek
來測試Length
屬性是否受支持,並在該情況下反覆讀入單個緩衝區。請注意,儘管在閱讀時,流的長度可能會發生變化......
當然,File.ReadAllBytes
會更簡單,當您只需處理文件而不是一般流。
有一個很好的理由不承擔* *您可以一次性讀取它:在'Stream' API並不能保證它會在一個呼叫讀到的一切。 – 2009-12-29 12:20:27
'buffer'顯式設置爲文件的長度。所以你的第一段沒有真正回答這個問題。 – 2009-12-29 12:23:22