gpt4 book ai didi

delphi - 带偏移量的 TFileStream

转载 作者:行者123 更新时间:2023-12-03 14:47:29 26 4
gpt4 key购买 nike

我需要扩展 TFileStream,以便它可以处理不是从 0 偏移量开始,而是从用户定义的偏移量开始的文件。我的意思是它必须将用户定义的偏移量解释为流开始。我的代码是:


type
TSuFileStream = class(TFileStream)
protected
FOffset : int64;

procedure SetOffset(Offset : int64);

procedure SetSize(NewSize: Longint); override;
procedure SetSize(const NewSize: Int64); override;
public
constructor Create(const AFileName: string; Mode: Word); overload;
constructor Create(const AFileName: string; Mode: Word; Rights: Cardinal); overload;

function Seek(Offset: Longint; Origin: Word): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;

property Offset : int64 read FOffset write SetOffset;
end;
...
constructor TSuFileStream.Create(const AFileName: string; Mode: Word);
begin
inherited Create(AFileName, Mode);
FOffset := 0;
end;

constructor TSuFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
begin
inherited Create(AFileName, Mode, Rights);
FOffset := 0;
end;

procedure TSuFileStream.SetOffset(Offset : int64);
begin
FOffset := Offset;
inherited Seek(FOffset, soBeginning);
end;

procedure TSuFileStream.SetSize(NewSize: Longint);
begin
inherited SetSize(FOffset + NewSize);
end;

procedure TSuFileStream.SetSize(const NewSize: Int64);
begin
inherited SetSize(FOffset + NewSize);
end;

function TSuFileStream.Seek(Offset: Longint; Origin: Word): Longint;
begin
Result := Seek(Int64(Offset), TSeekOrigin(Origin));
end;

function TSuFileStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
case Origin of
soBeginning: Result := inherited Seek(FOffset + Offset, soBeginning) - FOffset;
soCurrent: Result := inherited Seek(Offset, soCurrent) - FOffset;
soEnd: Result := inherited Seek(Offset, soEnd) - FOffset;
end;
end;

但它无法正常工作。问题出在 Seek 函数中,但我不知道为什么。当我将此类流传递给第三方组件时,它仅在 TSuFileStream.Offset := 0;

时才有效

最佳答案

首先,仅覆盖其中一个方法版本。正如您从类接口(interface)中看到的,相同方法(如 setSize 和eek)同时具有 longint 和 int64 版本。这是在 Delphi 文档中。覆盖 int64 版本。

其次,我不会覆盖 TFilestream,而是直接覆盖 TStream 以创建要使用的“中间流”。

在构造函数中我会放置 2 个参数:

  1. 任何类型的实际源流
  2. 偏移量

所以基本上您想要创建的是真实流和自定义版本之间的代理。这样,在您的查找实现中,您必须将偏移量(查看 TMemoryStream 和 TFileStream 以了解它是如何完成的)添加到该位置。您还可以从支持任何类型的流源中受益。

您最终应该得到一个易于使用的代理:

mMyStream:=TMyProxyStream.Create(mRealStream,2800); //Root offset at 2800
try
mMyStream.Read(mBuffer,1024); // After read, offset = 3824
mMyStream.position:=0; //Reset offset back to to 2800
finally
mMyStream.free;
end;

查找功能的计算可能有点棘手。这是我为缓冲系统编码的代理类的一个示例(FOffset 是一个内部变量,这是您要操作的变量):

function TSLBufferStreamAdapter.Seek(const Offset:Int64;
Origin:TSeekOrigin):Int64;
Begin
Case Origin of
soBeginning:
Begin
if Offset>=0 then
FOffset:=Math.EnsureRange(Offset,0,FBufObj.Size);
end;
soCurrent:
Begin
FOffset:=math.EnsureRange(FOffset + Offset,0,FBufObj.Size);
end;
soEnd:
Begin
If Offset>0 then
FOffset:=FBufObj.Size-1 else
FOffset:=math.EnsureRange(FOffset-(abs(Offset)),0,FBufObj.Size);
end;
end;
result:=FOffset;
end;

我现在更新此回复以包含更新链接。我的图书馆 byterage已转移到谷歌代码 - 看看那里。希望对您有帮助!

关于delphi - 带偏移量的 TFileStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5980513/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com