我正在使用TIdHTTP.Get()將(可能很大)檔案檢索到TFileStream, 基本上;
filestream := TFileStream.Create(destination, fmCreate);
http.HandleRedirects := True;
try
http.Get(url, filestream);
except
on E: Exception do Memo.Lines.Add(E.Message);
end;
filestream.Free;
我的問題是當/如果用戶在下載程序中關閉/終止程式。檔案大小不會顯示為小于應有的大小,而是顯示已完成下載的大小。這是為什么?
我使用檔案大小作為快速檢查以查看下載是否成功,因此具有正確的大小,但錯誤的內容會導致其他錯誤。我不想對每個檔案進行散列校驗和,因為它們有很多,并且 MD5 檢查需要一段時間來處理更大的多 GB 大小的檔案。
如果下載因任何原因中斷,有沒有辦法縮小目標檔案的大小?除非所有下載都已完成,否則不將流擴展到完整大小的某種方法好嗎?
uj5u.com熱心網友回復:
如果檔案大小在下載開始時已知,即在 HTTPContent-Length標頭中,則TIdHTTP(更具體地說,TIdIOHandler.ReadStream())將流預先分配為完整大小以提高下載期間的 I/O 性能。
如果下載(不是應用程式)過早終止,則ReadStream()具有減小流大小以匹配下載的實際位元組的邏輯。因此,在這種情況下,除非下載完成,否則檔案不應保留完整大小。
但是,如果用戶終止應用程式,則該代碼將不會運行,因此是的,檔案將保留為預先分配的大小。目前 Indy 中沒有禁用該預分配邏輯的選項。實際上,代碼中有一個 TODO 項。
同時,有一個簡單的解決方法 - 您可以從自定義類派生TFileStream并覆寫其虛擬SetSize()方法(Size屬性的 setter)以不執行任何操作。Indy 不會驗證實際應用了請求的大小。只要流的Size和Position屬性 getter 作業正常,你應該沒問題。
type
TFileStreamNoPreSize = class(TFileStream)
protected
procedure SetSize(const NewSize: Int64); override;
end;
procedure TFileStreamNoPreSize.SetSize(const NewSize: Int64);
begin
// do nothing...
end;
...
filestream := TFileStreamNoPreSize.Create(destination, fmCreate);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/373129.html
