2011-05-12 12 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

TGpStreamWindow का उपयोग करें, my web पर और 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; 
8

सबसे पहले, केवल विधि संस्करणों में से एक को ओवरराइड। आप कक्षा इंटरफ़ेस से देख सकते हैं आप एक ही तरीके के दोनों longint और int64 संस्करण है (setSize तरह छुपी)। यह डेल्फी दस्तावेज में है। 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; 

तलाश कार्यक्षमता थोड़ा गणना करने के लिए मुश्किल हो सकता है।

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 कोड पर ले जाया गया है - वहां एक नज़र डालें। आशा करता हूँ की ये काम करेगा!

संबंधित मुद्दे