[英]Delphi: Copy FileStream to MemoryStream
我想將FileStream的一部分復制到MemoryStream。
FileStream.Write(Pointer(MemoryStream)^, MemoryStream.Size);
FileStream.Read(Pointer(MemoryStream)^, count);
那正確嗎? 它不適合我。
你必須從FileStream中將Read()放入一個單獨的緩沖區,然后將Write()放到MemoryStream中,即:
var
Buffer: PByte;
GetMem(Buffer, NumberOfBytes);
try
FileStream.ReadBuffer(Buffer^, NumberOfBytes);
MemoryStream.WriteBuffer(Buffer^, NumberOfBytes);
finally
FreeMem(Buffer);
end;
由於您正在處理兩個TStream對象,因此使用TStream.CopyFrom()方法會更容易,即:
MemoryStream.CopyFrom(FileStream, NumberOfBytes);
以下解決方案不使用單獨的緩沖區作為已發布的解決方案。 而是直接寫入目標內存流的緩沖區。 這是更快的,因為另一個解決方案復制兩次,首先進入臨時緩沖區,最后進入內存流。
...
try
MemoryStream.SetSize(NumberOfBytes); // Allocating buffer
FileStream.ReadBuffer(MemoryStream.Memory^, NumberOfBytes);
finally
MemoryStream.Free();
...
這是有效的,因為SetSize還分配內存流的緩沖區。 請參閱SetSize文檔 。
使用SetSize在填充數據之前設置內存流的大小。 SetSize分配內存緩沖區以保存NewSize字節[...]。
我還使用CopyFrom測試了該解決方案,但該解決方案使用巨型文件非常慢,因為它似乎使用非常小的緩沖區。
如果要使用上面的方法直接讀取文件,可以使用自己的函數來完成,該函數直接將塊讀取到內存流中。 為了比CopyFrom方法更快,這些塊應該更大。 以下代碼使用靈活的緩沖區,例如256 MiB。 請隨意使用它。
var
...
MemoryStreamPointer: Pointer;
BlockSize: Integer;
BytesToRead: Integer;
BytesRead: Integer;
RemainingBytes: Integer;
begin
...
BlockSize := 256 * 1024 * 1024; // 256 MiB block size
MemoryStream.SetSize(NumberOfBytes); // Allocating buffer
MemoryStreamPointer := MemoryStream.Memory;
RemainingBytes := NumberOfBytes;
while RemainingBytes > 0 do
begin
BytesToRead := min(RemainingBytes, BlockSize);
BytesRead := FileStream.Read(MemoryStreamPointer^, BytesToRead);
RemainingBytes := RemainingBytes - BytesRead;
MemoryStreamPointer := Pointer(NativeInt(MemoryStreamPointer) + BytesRead);
end;
...
end;
請注意,上面的代碼不包含錯誤處理。 進一步考慮在讀取之前將文件流位置設置為0。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.