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
Antwort Antwort
Seite 1 von 2  1 2      
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
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 19. Jul 2007, 13:06
Die sinnvollste Variante ist es einen MemoryStream zu nehmen. Denn sobald die Größe nicht mehr in den normalen Ram passt lagert Windows sowieso in das SwapFile aus. Warum gerade diese Größe (5MB)?

[OT]
folgendes solltest du vermeiden und dir gar nicht erst angewöhnen
if inMemory=true then [/OT]

[Edit]
Ich finde die Idee recht interessant einen "ReadOnly" Stream zu haben und nur die Änderungen gesondert zu speichern. Wenn du nichts dagegen hast würde ich die Idee gern versuchen umzusetzen.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

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

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 19. Jul 2007, 13:30
Ja, im moment Arbeitet mein Programm mit einem MemoryStream. Allerdings dauert das auslagern so ewig.

Beispiel: Ich lade manchmal relativ große Dateien in den Memorystream. Dabei macht ja windows dann nix anderes als Auslangern, also im Grunde "nochmal ne Kopie der Daten in der Auslangerungsdatei" anlegen.
Wenn ich jetzt aber die eigenschaften eines Filestreams hätte, müsste nix nochmal ausgelagert werden, alles ginge ganz fix und ich wäre glücklich. Problem nur: Ich muss aber leider Daten in den Stream schreiben, weswegen dadurch meine Originaldateien kaputt gehen würden.

Wichtig ist mir noch: Wenn ich jetzt nur die Änderungen speichere, müssten die sich auch von selbst in temporäre Dateien schreiben, falls sie Größer als die swapsize werden. Hm...ich finde es ist irgendwie relativ schwer zu beschreiben...

5mb hab ich einfach mal als Beispiel genommen, du kannst ja auch meinetwegen 50 mb nehmen....vollkommen egal... solange es halt noch in dem Ram passt...

Klar kannst du dich mal dran versuchen, wie gesagt, bin für jede Idee dankbar
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#4

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 19. Jul 2007, 15:39
Nette Stream-Idee. Vielleicht mache ich eine Variante fuer die JCL. Da haben wir ein Sortiment abseitiger, aber nuetzlicher Streams.
Fuer diesen Stream ist es wichtig das er die Datei in der richtigen Directory anlegt und das im Konstruktor erledigt, damit ein Problem bei der Dateierstellung nicht erst spaeter auftritt.
Weiss jemand wie das bei Vista geregelt ist? Ist es sichergestellt das die Directory in der Environment-Variable TEMP auch fuer alle Benutzer schreibbar ist?
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

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

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 19. Jul 2007, 15:58
Schätze mal, dass Vista %Temp% immer noch kennt.

Danke, Robert für das Lob Mein Hauptproblem im Moment ist, dass ich nicht weiß wie ich "zwei Buffer" zusammenfasse: Beispiel:


http://lanfs.la.funpic.de/b1.jpg

TExtendetStream.Position:=110;
TExtendetStream.Read(Buffer,150);

Dann muss ich mir meinen Buffer aus dem Buffer vom Changestream und dem vom Originalstream zusammenbasteln...wie mache ich das am besten?
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#6

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 19. Jul 2007, 16:09
Das Problem ist nicht das Vista TEMP kennt, sondern ob die Directory sicher fuer alle Benutzer schreibbar ist. Ich habe schon viel von den MS-Programmierern erlebt und bin auf alles gefasst. Windows hatte nie ein so weitgehendes Konzept von Temporaerdateien wie Unix.
Bei deinem Pufferproblem habe ich gerade keine Lust dir zu helfen. Morgen vielleicht.
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#7

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 19. Jul 2007, 18:44
Hallo,

warum sollte das Temp-Verzeichnis für alle User beschreibbar sein? Jeder User hat doch sein eigenes Temp-Verzeichnis. Unter Vista ist das "C:\Users\<UserName>\AppData\Local\Temp", unter XP "C:\Dokumente und Einstellungen\<UserName>\Lokale Einstellungen\Temp".
Das Verzeichnis "C:\Windows\Temp" erlaubt aber immer noch allen Benutzern das Anlegen von Dateien.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#8

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 20. Jul 2007, 05:46
Ich habe gerade gesehen das jemand gerade an JclBufferedStream arbeitet. Da duerfte diese Idee ziemlich genau dazupassen. Ich sag ihm mal bescheid.
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

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

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 20. Jul 2007, 12:29
Hey, Robert! Dankeschön für deine Mithilfe!

Also wenn ich das User Account Control System von Vista richtig verstanden habe (habs nur überflogen) können Benutzer und Anwendungen in die zum Benutzerprofil gehörigen Ordner natürlich ohne Beschränkung schreiben und lesen, also auch in die entsprechenden Temp Folder. Für alle anderen Zugriffe auf Systemordner u.Ä. legt Windows für jeden User eine Art virtuelles Dateisystem an. Hier ein paar Infos dazu, die hoffentlich weiterhelfen:

http://www.microsoft.com/technet/tec...lt.aspx?loc=de
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Stream Ableitung, mit Eigenschaften von File- und Memstr

  Alt 20. Jul 2007, 13:39
Zu Beitrag #5
Am einfachsten wäre es wenn man sich eine Liste macht wo die ganzen geänderten Buffer aufgeführt sind mit fester Größe. Wird etwas geschreiben suchst du also einfach ob der Bereich schon in der Liste der geänderten Teile ist. Wenn ja dann wird in dem teil gearbeitet. Wenn nicht wird der angelegt
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 19:35 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