Jun*_*orD 8 delphi stream tfilestream tstream
我需要扩展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;
Run Code Online (Sandbox Code Playgroud)
但它不起作用.问题在于寻求功能,但我不知道为什么.当我将这样的流传递给第三方组件时,它仅在TSuFileStream.Offset:= 0时起作用;
首先,只覆盖其中一个方法版本.从类接口可以看出,你有longint和int64版本的相同方法(比如setSize和seek).这是在Delphi文档中.覆盖int64版本.
其次,我不会覆盖TFilestream而是直接使用TStream创建一个"在流之间"来使用.
在构造函数中,我将放置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;
Run Code Online (Sandbox Code Playgroud)
搜索功能可能有点难以计算.这是我为我的缓冲系统编码的代理类的一个例子(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;
Run Code Online (Sandbox Code Playgroud)
我现在更新此回复以包含更新链接.我的图书馆字节已经转移到谷歌代码 - 看看那里.希望能帮助到你!
使用TGpStreamWindow,可以在我的网站和Google Code上找到。
用法:
var
offsetStream: TGpStreamWindow;
begin
offsetStream := TGpStreamWindow.Create(originalStream, initialOffset, originalStream.Size - 1);
try
DoSomethingWith(offsetStream);
offsetStream.SetWindow(anotherInitialOffset, originalStream.Size - 1);
DoSomethingElseWith(offsetStream);
finally FreeAndNil(offsetStream); end;
end;
Run Code Online (Sandbox Code Playgroud)