2011-05-12 6 views
8

TFileStream을 확장해야 파일이 0 오프셋이 아닌 사용자 정의 오프셋에서 작동 할 수 있습니다. 나는 사용자 정의 오프셋을 스트림 시작으로 해석해야 함을 의미합니다. 내 코드 :오프셋이있는 TFileStream


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; 

하지만 제대로 작동하지 않습니다. 문제는 탐색 기능에 있지만 왜 그런지 모르겠습니다. 이러한 스트림을 타사 구성 요소에 전달할 경우 TSuFileStream.Offset : = 0;

답변

2

my webGoogle Code에서 사용할 수있는 TGpStreamWindow을 사용하십시오.

사용법 :

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; 
8

먼저 메소드 버전 중 하나만 대체하십시오. 클래스 인터페이스에서 볼 수 있듯이 동일한 메소드 (setSize 및 seek와 같은)의 longint 및 int64 버전이 모두 있습니다. 이것은 Delphi 문서에 있습니다. int64 버전을 재정의하십시오.

두 번째로 TFilestream을 오버라이드하지 않고 TStream을 직접 사용하여 작업 할 "스트림 사이"를 만듭니다. 그래서 기본적으로 만들려는 어떤 실제 스트림 사이의 프록시는

  • 오프셋 모든 유형의

    1. 실제 소스 스트림 : 생성자에서

      나는이 개 매개 변수를 둘 것 귀하의 사용자 정의 버전. 그런 식으로, 당신의 탐색 구현에서, 위치에 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; 
      

      시크 기능은 계산하기 까다로운 조금 할 수 있습니다.

      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; 
      

      내가 업데이트 링크를 포함하는 지금이 답변을 업데이트 : 여기에 내가 내 버퍼 시스템에 대한 코딩 된 프록시 클래스의 예입니다 (FOffset 내부 변수 인, 이것은 당신이 조작 할 일이다). 내 라이브러리 byterage이 (가) Google 코드로 이동했습니다. 희망이 도움이됩니다!

    관련 문제