带偏移量的 TFileStream
我需要扩展 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; 时才有效。
I need to extend TFileStream so that it can work with a file not from 0 offset, but from user defined offset. I mean it must interpret user defined offset as stream beginning. My code is:
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;
but it does not work propertly. The problem is in Seek function but I don't know why. When I pass such stream to a third party component it works only if TSuFileStream.Offset := 0;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,仅覆盖其中一个方法版本。正如您从类接口中看到的,相同方法(如 setSize 和eek)同时具有 longint 和 int64 版本。这是在 Delphi 文档中。覆盖 int64 版本。
其次,我不会覆盖 TFilestream,而是直接覆盖 TStream 以创建要使用的“中间流”。
在构造函数中,我将放置 2 个参数:
所以基本上您想要创建的是真实流和自定义版本之间的代理。这样,在您的查找实现中,您必须将偏移量(查看 TMemoryStream 和 TFileStream 以了解它是如何完成的)添加到该位置。您还可以从支持任何类型的流源中受益。
您最终应该得到一个易于使用的代理:
查找功能可能有点难以计算。这是我为缓冲系统编码的代理类的一个示例(FOffset 是一个内部变量,这是您想要操作的变量):
我现在更新此回复以包含更新链接。我的库 byterage 已移至 Google 代码 - 看看那里。希望有帮助!
First, only override one of the method versions. As you can see from the class interface you have both longint and int64 versions of the same methods (like setSize and seek). This is in the Delphi documentation. Override the int64 versions.
Secondly, I would not override TFilestream but rather TStream directly to create a "in between stream" to work with.
In the constructor I would put 2 parameters:
So basically what you want to create is a proxy between the real stream and your custom version. That way, in your seek implementation all you have to add the offset (look at TMemoryStream and TFileStream to see how it's done) to the position. You also get the benefit of supporting any type of stream-source.
You should end up with a proxy that is easy to use:
The seek functionality can be a bit tricky to calculate. Here is an example from a proxy class i coded for my buffer system (FOffset being an internal variable, this is the one you want to manipulate):
I update this reply now to include an update link. My library byterage has moved to google code - have a look there. Hope it helps!
使用 TGpStreamWindow,可在我的网站和Google 代码 。
用法:
Use TGpStreamWindow, available on my web and on Google Code.
Usage: