AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Stream Ableitung, mit Eigenschaften von File- und Memstream?
Thema durchsuchen
Ansicht
Themen-Optionen

Stream Ableitung, mit Eigenschaften von File- und Memstream?

Ein Thema von alleinherrscher · begonnen am 19. Jul 2007 · letzter Beitrag vom 21. Jul 2007
 
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#1

Stream Ableitung, mit Eigenschaften von File- und Memstream?

  Alt 19. Jul 2007, 13:03
Hi, ich bin auf der suche nach einer Art intelligentem Stream, der von TStream abgeleitet ist, und zunächst die selben eigenschaften hat wie ein Memorystream. Wird aber eine bestimmte Größe im Speicher erreicht, soll er die Daten praktisch auslagern und dann so funktionieren wie ein Filestream. (es wird eine temporäre Datei erstellt).
Warum ich nicht direkt einen Filestream benutzte? Ich bräuchte eine Art filestream, in den man per Write(Buffer, count) daten schreiben kann, ohne die Originaldatei zu verändern. Nun könnte man auf die Idee kommen, einfach eine Kopie der Originaldatei anzulegen. Aber das kann bei großen Dateien ja schonmal ewig dauern und viel Zeit kosten.

Dafür habe ich hier mal ein bisschen was rumexperimentiert, ist alles noch was unschön programmiert, sind erst erste versuche: Ist mein Stream kleiner als 5mb, wird er im speicher gehalten. Danach wird eine temporäre Datei (0.part 1.part usw) erzeugt, in welche die Daten geschrieben werden und dann per Filestream benutzt werden.
Wird ein Stream aus einer vorhandenen Datei geladen, so ist sie "protected". D.h. schreibt man per write neue Daten in den Stream, werden nur die änderungen in einem seperaten Stream gespeichert (ChangeSave).

Ich hab den Code mal angehängt. Vielleicht kann mir jemand ein paar Tipps geben, wie das ganze etwas "schöner" zu programmieren ist. Konkret hänge ich bei dem "read" befehl. Ich versuche grade aus dem ChangeSave (also den gemachten Änderungen) und dem Originalfilestream wieder den gewünschten Stream zusammen zu bauen.

Also bitte nicht hauen, weils unsauber geschrieben ist...

Delphi-Quellcode:

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;


  type
   TExtendedStream = class(TStream)
     Constructor Create(OpenFromFilename:string);
     function write(Const Buffer;Count:integer):integer;
     function read(var Buffer;Count:integer):integer;
  private
    { Private-Deklarationen }
    aStream:TStream;
    ChangeSave:TExtendedStream;
    protect:boolean;
    inMemory:boolean;
    swapsize:integer;
  public
    Size:int64;
        Position:int64;
    { Public-Deklarationen }
  end;



implementation

function GetTempFileName(TempDirectory:String):string;
var filename:string;
    i:integer;
begin
i:=0;
filename:=inttostr(i)+'.part';
while fileexists(TempDirectory+filename) do
begin
  inc(i);
  filename:=inttostr(i)+'.part';
end;
result:=TempDirectory+filename;
end;

function GetFileSize(szFile: PChar): Int64;
var
  fFile : THandle;
  wfd : TWIN32FINDDATA;
begin
  result := 0;
  if not FileExists(szFile) then exit;
  fFile := FindFirstfile(pchar(szFile), wfd);
  if fFile = INVALID_HANDLE_VALUE then exit;
  result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  windows.FindClose(fFile);
end;

constructor TExtendedStream.Create(OpenFromFilename:string);
begin
swapsize:=5242880;
ChangeSave:=nil;

if OpenFromFilename='then
  begin
    aStream:=TMemoryStream.Create;
    inMemory:=True;
    Position:=0;
    Size:=0;
    protect:=False;
  end
else
  if fileexists(OpenFromFilename) then
    if GetFileSize(pChar(OpenFromFilename))<swapsize then
      begin
        aStream:=TMemoryStream.Create;
        TMemoryStream(aStream).LoadFromFile(OpenFromFilename);
        inMemory:=True;
        protect:=False;
        Position:=0;
        Size:=0;
      end
    else
      begin
        aStream:=TFilestream.Create(OpenFromFilename,fmOpenRead);
        inMemory:=False;
        protect:=true;
        Position:=0;
        Size:=astream.Size;
      end;
end;

function TExtendedStream.write(Const Buffer;Count:integer):integer;
var dummystream:TMemorystream;
    len:integer;
begin

  if inMemory=true then
  if sizeof(Buffer)+TMemorystream(aStream).size<swapsize then
  begin
    TMemorystream(aStream).Position:=self.Position;
    TMemorystream(aStream).Write(Buffer,count);
    size:=TMemorystream(aStream).Size;
    position:=TMemorystream(aStream).position;
  end
  else
    begin //swapen
      dummystream:=TMemorystream(aStream);
      aStream:=TFilestream.Create(GetTempFileName('C:\'),fmcreate);
      dummystream.Position:=0;
      Tfilestream(aStream).CopyFrom(dummystream,dummystream.size);
      freeandnil(dummystream);
      inMemory:=False;
      protect:=false;
      Tfilestream(aStream).Position:=self.Position;
      Tfilestream(aStream).Write(Buffer,count);
      size:=Tfilestream(aStream).Size;
      position:=Tfilestream(aStream).position;
    end
  else //inMemory=false
    if not protect then
      begin
        TFileStream(aStream).position:=position;
        TFileStream(aStream).Write(Buffer,count);
        size:=Tfilestream(aStream).Size;
        position:=Tfilestream(aStream).position;
      end
    else
      begin //in Memory=false protect=true
        if ChangeSave=nil then
          begin
            ChangeSave:=TExtendedStream.create('');
            ChangeSave.Position:=0;
          end;
            ChangeSave.Position:=ChangeSave.Size;
            ChangeSave.write(self.Position,sizeof(self.Position));
            len:=sizeof(buffer);
            ChangeSave.write(len,sizeof(len));
            ChangeSave.write(Buffer,Count);
      end;
end;

function TExtendedStream.read(var Buffer;Count:integer):integer;
var dummystream:TMemorystream;
    pos,len:integer;
    rel_start,rel_end:integer;
begin

  if inMemory=true then
  begin
    TMemorystream(aStream).Position:=self.Position;
    TMemorystream(aStream).read(Buffer,count);
    position:=TMemorystream(aStream).position;
  end
  else //inMemory=false
    if not protect then
      begin
        TFileStream(aStream).position:=position;
        TFileStream(aStream).Read(Buffer,count);
        position:=Tfilestream(aStream).position;
      end
    else
      begin //in Memory=false protect=true
        if ChangeSave<>nil then
          begin
            ChangeSave.Position:=0;
            ChangeSave.read(pos,sizeof(pos));
            ChangeSave.read(len,sizeof(len));
            rel_start:=position-pos;
            rel_end:=(position+count)-(pos+len);
            if rel_start>=0 then
              if rel_end>=0 then //readstream komplett in Changestream
                begin
                  ChangeSave.Position:=ChangeSave.Position+rel_start;
                  ChangeSave.read(Buffer,count);
                  ChangeSave.Position:=ChangeSave.Position+rel_end;
                end
              else
                begin //Readstream Ende liegt außerhalb von Changestream
                  ChangeSave.Position:=ChangeSave.Position+rel_start;
                  ChangeSave.read(Buffer,count+rel_end);
                  {hier hänge ich grade etwas}

                end;

          end;

      end;







end;



end.
Bin für alle Vorschläge dankbar.

Grüße Alleinherrscher
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz