Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Filestream, string anhängen (https://www.delphipraxis.net/106799-filestream-string-anhaengen.html)

Muetze1 17. Jan 2008 19:37

Re: Filestream, string anhängen
 
Zitat:

Zitat von HannosG
oder mit
Delphi-Quellcode:
FS.Seek(-1*Count,soFromEnd);

Ich war bisher der Meinung, dass die Angaben positiv sein müssen bei soFromEnd - aber gut, dann halt negativ. Aber warum führst du nun noch eine Multikplikation durch, anstatt einfach nur den negativen Wert zu übergeben? Also einfach -Count angeben im Seek...

Aber ich habe eben nochmal geschaut, Seek will trotzdem ein negativen Wert haben. Die Origin Angabe ist nur der Ausgangspunkt, bewirkt aber nichts an der Bedeutung des Offsets (ausser bei soFromBeginning, dort wird der Wert dann als unsigned interpretiert laut WinAPI).

Hier dann nochmal mein korrigierter Code:

Delphi-Quellcode:
function GetFileStrFromEnd(FileName: String; Count: Integer): String;
var
  FS: TStream;
  I: integer;
begin
  result := ''; // stream ist kleiner

  FS := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive);
  try
    if FS.Seek(-Count, soFromEnd) = FS.Size - Count then
    begin
      Setlength(Result,Count);
      FS.Read(Result[1],Count);
    end;
  finally
    fs.Free;
  end;
end;

eLse-maestro 17. Jan 2008 21:49

Re: Filestream, string anhängen
 
Delphi-Quellcode:
function GetFileStrFromEnd(FileName: String): String;
var
  FS: TStream;
  I,count: integer;
 
begin
count:=0;
  result := ''; // stream ist kleiner

  FS := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive);
  try
    while pos('[data]',result)=0 do
      begin
        if FS.Seek(-Count, soFromEnd)=fs.Size then exit    \\ noch ein fehler drin
        else                                               \\ schaue morgen danach, Gute Nacht.
          begin
            if FS.Seek(-Count, soFromEnd) = FS.Size - Count then
            begin                                              
               Setlength(Result,Count);
               FS.Read(Result[1],Count);
            end;
            inc(count);
          end;
      end;
  finally
    fs.Free;
  end;
end;

habe mal muetzes code angepasst.. villeicht brauch das ja jemand..
mein string fängt mit '[data]' an.

und irgendwie wollte meine if anweisung kein "if not count=fs.size then..." aktzeptieren, dann habe ich es mal so gedreht ;)

himitsu 17. Jan 2008 22:10

Re: Filestream, string anhängen
 
Delphi-Quellcode:
if not (count = fs.Size) then

//oder besser

if count <> fs.Size then

if count < fs.Size then
Delphi-Quellcode:
function GetFileStrFromEnd(FileName: String): String;
var
  FS: TStream;
  I,count: integer;
 
begin
count:=0;
  result := ''; // stream ist kleiner

  FS := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive);
  try
    while (count <= fs.Size) and (pos('[data]',result) = 0) do
    begin
      if FS.Seek(-Count, soFromEnd) = FS.Size - Count then
      begin
        Setlength(Result,Count);
        FS.Read(Result[1],Count);
      end;
      inc(count);
    end;
    if pos('[data]',result) = 0 then result := ''; // fals string nicht gefunden wurde
  finally
    fs.Free;
  end;
end;
wie groß ist deine Datei, bzw. wie lang ist der String maximal, den du suchst?

so ließt du ja die Datei mehrmals vom Ende her ein ... Length(Result)-mal

Count=0 wurd es eh nicht geben und wenn dein String mit [data] anfängt, dann kannst bei der Vorgehensweise du auch gleich bei count=Length('[data]'); oder count=6; anfangen, den kürzer kann der String nicht sein.


falls die Maximalläge nicht feststeht und du nicht immer einen genügendgroßen Block auslesen willst, dann
könnte man auch in größeren Schritten zurückgehn (nicht nur 1 > inc(count), sondern gleich ein paar byte mehr



oder du ließt gleich nur einmal einen größer Block (ganze Datei, oder soviel wie der String maximal lanhg ist) aus, suchst darin den Stringanfang und kopierst dir ab dem Fundort den String bis Datei-/Blockende in Result rein.
Delphi-Quellcode:
FS.Seek(-1024, soFromEnd); // 1024 = 1 KB
SetLength(Result, 1024);
FS.Read(Result[1], 1024);
Result := Copy(Result, Pos('[data]', Result), 1024);
// statt Copy  Delete(Result, 1, Pos('[data]', Result) - 1);



erstellst du die Datei selber?
wenn ja, dann speicher doch die Stringgröße (siehe oben), dann kannst die Auslesen und du weißt wo der String ist.

Dieses Länge/Größe kann man auch nach dem String speichern (nicht immer nur davor, wie oben sichtbar)
Delphi-Quellcode:
FS.Seek(-SizeOf(Len), soFromEnd);
FS.Read(Len, SizeOf(Len));
FS.Seek(-SizeOf(Len) - Len, soFromEnd);
SetLength(Result, Len);
FS.Read(Result[1], Len);

> alles in Kurz und ohne Fehlerprüfung und sowas

eLse-maestro 17. Jan 2008 22:16

Re: Filestream, string anhängen
 
das problem ist, das der string mal so mal so lang ist, und nicht konstant..

mir kommt aber gerade die idee, das der "builder" ja die zeichen länge des strings anhängen kann.. dann kann man das auslesen
und die while schleife weg lassen..

die datei ist so um die 400kb groß, also um ressourcen mache ich mir nicht so große gedanken..

gute nacht :)

himitsu 17. Jan 2008 22:25

Re: Filestream, string anhängen
 
Delphi-Quellcode:
function GetFileStrFromEnd(FileName: String): String;
var
  FS: TStream;
  i: integer;
 
begin
  FS := TFileStream.Create(FileName, fmOpenRead or fmShareExclusive);
  try
    if FS.Size > 0 then
    begin
      FS.Position := 0;
      SetLength(Result, FS.Size);
      FS.Read(Result[1], FS.Size);
      i := Pos('[data]', Result);
      if i > 0 then Delete(Result, 1, i - 1) else Result := '';
    end
    else
      Result := '';
  finally
    FS.Free;
  end;
end;
wenn du das [data] nicht willst, dann einfach bei "i - 1" diese Länge einrechnen, also "i + 5"


und für die idealere Variante (siehe dem Code mit 1024 im letzten Beitrag), ... und dort einfach einen Wert wählen, der auf jeden Fall groß genug ist ^^

Muetze1 18. Jan 2008 00:33

Re: Filestream, string anhängen
 
Ich würde bei sowas eher MMF (memory mapped filestream) verwenden, damit solltest du das viel schneller lesen, also dieses blockweise "von hinten nach vorne seeken".


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:27 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz