我花了幾個小時在這上面,當我發現解決方案時,我正要從椅子上摔下來......
我正在讀取未壓縮的 6Gb AVI 檔案。
在 Delphi 10.4 中使用這個變數來處理檔案:
VideoFile:THandleStream;
...
VideoFile := THandleStream.Create(FileHandle);
我意識到從下面搜索0x7FFFFFFF時可以,但上面不行。
當我查看宣告時,Offset是一個Int64,好的:
function THandleStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
Result := FileSeek(FHandle, Offset, Ord(Origin));
end;
然后FileSeek()到這里......一個32位有符號整數......乍一看我沒有進入。大錯特錯!
function FileSeek(Handle: THandle; Offset, Origin: Integer): Integer;
begin
{$IFDEF MSWINDOWS}
Result := SetFilePointer(Handle, Offset, nil, Origin);
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
Result := lseek(Handle, Offset, Origin);
{$ENDIF POSIX}
end;
這真的很討厭而且非常非常糟糕...... 為什么 Embarcadero 選擇了這種誤導性的實作?
我已經習慣VideoFile.Position := XXXX了克服這個問題。但是為什么要離開Int64呢THandleStream.Seek()?
uj5u.com熱心網友回復:
你的診斷不正確。
有兩個版本FileSeek()- 32 位版本和 64 位版本:
function FileSeek(Handle: THandle; Offset, Origin: Integer): Integer;
begin
{$IFDEF MSWINDOWS}
Result := SetFilePointer(Handle, Offset, nil, Origin);
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
Result := lseek(Handle, Offset, Origin);
{$ENDIF POSIX}
end;
function FileSeek(Handle: THandle; const Offset: Int64; Origin: Integer): Int64;
{$IFDEF MSWINDOWS}
begin
Result := Offset;
Int64Rec(Result).Lo := SetFilePointer(Handle, Int64Rec(Result).Lo,
@Int64Rec(Result).Hi, Origin);
if (Int64Rec(Result).Lo = $FFFFFFFF) and (GetLastError <> 0) then
Int64Rec(Result).Hi := $FFFFFFFF;
end;
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
begin
Result := lseek(Handle, Offset, Origin);
end;
{$ENDIF POSIX}
您只查看 32 位版本FileSeek(),但THandleStream覆寫 64 位版本TStream.Seek()以呼叫 64 位版本FileSeek()。
THandleStream.Seek()正在傳遞 a THandle、 anInt64和 a Byteto FileSeek(),那么您認為會呼叫哪個版本?64位版本。在這兩種情況下,編譯器都可以將 a 放大Byte為 an ,但是當它可以按原樣傳遞時Integer,它不會將 an 縮小Int64為 an 。因此 64 位版本更適合正在傳遞的內容。IntegerInt64FileSeek()THandleStream.Seek()
如果不是這種情況,那么您的主張是:
我已經習慣
VideoFile.Position := XXXX了克服這個問題。
不會是真的,因為setter 方法只是呼叫您聲稱遇到問題TStream.Position的相同 64 位方法:Seek()
procedure TStream.SetPosition(const Pos: Int64);
begin
Seek(Pos, soBeginning); // <-- soBeginning is from TSeekOrigin
end;
因此,無論您實際遇到什么麻煩,都不是因為 64bitTHandleStream.Seek()呼叫 32bit FileSeek()。這根本不是THandleStream作業原理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/503907.html
標籤:德尔福
