【问题标题】:TFileStream with offset带偏移量的 TFileStream
【发布时间】:2012-04-29 23:32:09
【问题描述】:

我需要扩展 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;

【问题讨论】:

    标签: delphi stream tfilestream tstream


    【解决方案1】:

    首先,只覆盖其中一个方法版本。从类接口中可以看出,您拥有相同方法的 longint 和 int64 版本(如 setSize 和 seek)。这在 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 已移至谷歌代码 - 看看那里。希望对您有所帮助!

    【讨论】:

      【解决方案2】:

      使用TGpStreamWindow,在my webGoogle 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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-16
        • 2012-12-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 2012-08-25
        • 1970-01-01
        相关资源
        最近更新 更多