![]() |
FileToString: Wie String zu "StringToFile?"
Hallo DP,
Der Code aus der DP funktioniert ganz gut. Aber mit den StringToFile stehe ich auf dem Kriegsfuss. Für mein Tool, dass ich der DP Delphi Cleaner zur Verfügung gestellt habe, läuft die CopyDir wahrscheinlich zu langsam. Daher habe ich alle Files schon beim Suchen über FiletoString eingelesen. Nun bauche ich alle Strings wieder als File... Nur wie? Hier der funktionierende Code aus der DP:
Delphi-Quellcode:
Könnt Ihr mir wieder mal weiterhelfen? :thumb:
function FileToString(const FileName: string): AnsiString;
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try Len := fs.Size; SetLength(Result, Len); if Len > 0 then fs.ReadBuffer(Result[1], Len); finally fs.Free; end; end; Beste Grüße Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Schon mal mit .WriteBuffer versucht?
|
Re: FileToString: Wie String zu "StringToFile?"
Hallo, mkinzler, nett dass Du bei mir reinsiehst.
Ähm, das ist ja das Problem. Tstream.read und write habe ich mir schon im Tutorial der dsdt.de angesehen. Wie setzte ich denn den Code oben um? Wäre ja nicht nur für mich interessant. Also ich habe mal jetz so angefangen. Natürlich könnte ich wohl eine Fehlermeldung zurückgeben, wenn der Stream nicht korrekt geschreiben wurde.
Delphi-Quellcode:
So funktioniert es ja nicht. Das Result ist ein Schmarren, weil ich ja eine Procedure habe.
Procedure StringToFile(VAR FileName, Str: string);
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try Len := fs.Size; SetLength(Result, Len); if Len > 0 then fs.WriteBuffer(Result[1], Len); finally fs.Free; end; end; Magst Du den Code mal verbessern? :pale: |
Re: FileToString: Wie String zu "StringToFile?"
Delphi-Quellcode:
so müsstes gehn :)
Procedure StringToFile(VAR FileName, Str: string);
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try Len := Length(Str); fs.Write(Len, SizeOf(Integer)); fs.Write(Str[1], Len); finally fs.Free; end; end; Gruß Neutral General |
Re: FileToString: Wie String zu "StringToFile?"
Hallo,
seid ihr sicher, dass das stimmt :?:
Delphi-Quellcode:
Ich denke wenn man in den Stream reinschreiben möchte sollte man ihm das auch sagen :)
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
Delphi-Quellcode:
mfg Leonard
fs := TFileStream.Create(FileName, fmCreate);
|
Re: FileToString: Wie String zu "StringToFile?"
Ich habe gerade noch über den Code gegrübelt und den Vorschlag von mkinzler zum laufen gebracht. Ich probiere das gerade mal:
Delphi-Quellcode:
Ich habe keine Ahnung, ob es Wirklich geht. Mein Tool braucht mit CopyDir zu lange. Es wird noch dauern, bis ich weiss, ob und was letztendlich zuverlässig funzt... falls nicht, probiere ich Deinen Vorschlag, Neural general! Dankeschön schon mal vorab aun Euch [roter Kasten ] drei! Auf writebuffer wäre ich nicht gekommen. :thumb:
Procedure StringToFile(VAR FileName, Str: string);
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmCreate); try Len := fs.Size; SetLength(str, Len); if Len > 0 then fs.WriteBuffer(str[1], Len); finally fs.Free; end; end; Roter Kasten! Oha, Leonhard, ichglaube Du hast recht! Ändere ich gleich oben noch. |
Re: FileToString: Wie String zu "StringToFile?"
Hallo,
ich kann zwar keinen Sinn darin erkennen den Inhalt einer beliebigen Datei (binär?, riesig?) als String im Hauptspeicher zu lagern, aber wenn überhaupt, dann würde ich einen MemoryStream als Zwischenlager benutzen. Die Größe der ursprünglichen Datei darf natürlich nicht geschrieben werden, da so der Dateiinhalt verändert wird:
Delphi-Quellcode:
Getippt und nicht getestet.
procedure LoadStream(s: TStream; fn: TFileName);
var fs: TFileStream; begin fs := TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite); try s.CopyFrom(fs, fs.Size); s.Position := 0; finally fs.Free; end; end; procedure SaveStream(s: TStream; fn: TFileName); begin with TFileStream.Create(fn, fmCreate) do try s.Position := 0; CopyFrom(s, s.Size); finally Free; end; end; Freundliche Grüße vom marabu |
Re: FileToString: Wie String zu "StringToFile?"
@marabu
Na nun kann ich mich garnicht entscheiden... Es sind 951 Files mit insgesamt 1,79 MB. Alles überflüssige Dateien. Die lese ich gerade in eine Stringlist ein. Und nun statt 10 Minuten Backup mit Copydir, 10 Sekunden. Alles ist angelegt, aber die Files sind 0-Bytes. Mein Codde geht also nicht. War auch ein wenig zu schnell.. Ich probiere den Code von Neutral General aus. Natürlich mit der Änderung von Leonhard. Ca. 15 Sekunden! Ich sehe nach und 951 Files, 1,79 MB und 406 sind im Backupordner. Suuuuper! Ich hatte die Daten aber schon beim Suchen der betreffenden Files wegen der Performance in eine Stringlist eingelesen. Aber bei 1,91 MB. So der Zwischenstand. Ich probiere mal den Code von marabu auch aus. Der ist wohl für größere Dateien geeignet. Und dann gibt es nachher gleich ein Update von dem Tool Delhi Cleaner, ![]() Ihr dürft es gerne mal ansehen. Lasst Euch mal überraschen, wie viele entbehrliche Dateien Eure Festplatten belegen. Bis später... und vielen Dank! :thumb: :thumb: :thumb: |
Re: FileToString: Wie String zu "StringToFile?"
@Marabu
Mit den Streams scheitere ich leider schon bei den Übergabeparametern. Dein Code sieht aber interessant aus. Da benötige ich mehr LernZeit um ein Stream zu erstellen, damit ich den als Parameter Deinen Proceduren übergeben kann. Dies ist aber nicht allein das Problem. Es stellt sich ja die Frage der Weiterverarbeitung bzw. Zugriff der Daten. Aber das Problem ist ja gelöst: Hier nochmals der vollständige richtige Code, den ich verwendet habe, weil viele Threads oft die richtige Lösungen leider offen lassen, dass neue Thread notwendig werden. Daher der funktionierende und vollständige Code nachfolgend: FileToString:
Delphi-Quellcode:
Und wieder zurück mit StringToFile
function FileToString(const FileName: string): AnsiString;// inline;
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try Len := fs.Size; SetLength(Result, Len); if Len > 0 then fs.ReadBuffer(Result[1], Len); finally fs.Free; end; end;
Delphi-Quellcode:
EDIT: Nachträglich var in Const geändert, lt. marabu
Procedure StringToFile(const FileName, Str: string);//Inline;
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmcreate); try Len := Length(Str); fs.Write(Len, SizeOf(Integer)); fs.Write(Str[1], Len); finally fs.Free; end; end; Betraf ursprünglichen Code: Procedure StringToFile(VAR FileName, Str: string);//Inline; Inline verwende ich unter Turbo2006. Viel Vergnügen und beste Grüße. Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Guten Morgen.
Zitat:
Delphi-Quellcode:
Die Parameter der Prozedur StringToFile() solltest du besser als Konstanten übergeben. Ein Blick mit dem Windows Explorer auf das Dateisystem sollte dir offenbaren, dass die beiden Dateien aus meiner Testroutine einen Größenunterschied von 4 Byte aufweisen.
var
s: String; fn: TFileName; begin fn := ChangeFileExt(ParamStr(0), '.tmp'); s := FileToString(ParamStr(0)); StringToFile(fn, s); if FileToString(fn) = s then ShowMessage('passed') else ShowMessage('failed'); end; // procedure StringToFile(const FileName, Str: String); Zitat:
|
Re: FileToString: Wie String zu "StringToFile?"
@marabu
Vielen Dank für Deine Antwort, meine Routinen kopieren exakt. Die Files sind im Original und als Backup unverändert. Const funtioniert. Warum soll ich ein Const nehmem. Für mich ungewohnt... |
Re: FileToString: Wie String zu "StringToFile?"
Mein letzter Versuch: du schreibst in Zeile 9 der Prozedur StringToFile() aus deinem Beitrag #9 eine Längeninformation in die Datei, welche beim Einlesen noch nicht vorhanden ist. Dadurch haben die gelesene Datei und die geschriebene Datei nicht mehr den gleichen Inhalt. Bin ich denn der einzige hier, der das sieht?
Das Schlüsselwort CONST in der Signatur von StringToFile() dokumentiert für den kundigen Leser, dass die Argumente der Prozedur garantiert nicht inhaltlich verändert werden. In Verbindung mit dem Datentyp String erlaubt diese Vorgehensweise dem Compiler gewisse Optimierungsmaßnahmen zu ergreifen. Grüße vom marabu |
Re: FileToString: Wie String zu "StringToFile?"
Ok, auch in der Gefahr dass ich es nicht verstanden habe, damit können wir aber beide gut Leben, marabu.
Du meinst eine Datei, die wohl offen ist, bzw. während des Schreibens sich verändert. Dann kann der geschreibene Stream nicht stimmen. Klar. Aber das Problem kenne ich. Eine FileInUse lösch das Problem auch nicht. Nur ein Backup via Linux/BartCD. Aber in meinem Falle wäre es mit Spatzen auf Kanonen, sorry, anders rum, schießen. OK? Zitat:
Danke für Deine Mühe, marabu! Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Zitat:
Schönen Abend noch... Leonard |
Re: FileToString: Wie String zu "StringToFile?"
Neues Problem:
Der Code Filetostring und Stringtofile scheint die gelesen Daten auf der Festplatte noch offen zu haben; das Löschen geht nur, wenn mein Programm, das die Daten eingelesen hat, geschlossen wird. Gibt es ein Close dazu? Ich habe bei den Streams nachgesehen, konnte aber nichts finden. @marabu Ich habe mir den Code auch angesehen: Der Code schreibt in die Backups die Länge an den Anfang. :pale: Ich kann obigen Code nicht mehr ändern: Also den Code verwenden:
Delphi-Quellcode:
Vielen Dank Marabu, Dein Einwand war absolut berechtigt! :thumb:
function FileToString(const FileName: string): AnsiString;// inline;
var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try Len := fs.Size; SetLength(Result, Len); if Len > 0 then fs.ReadBuffer(Result[1], Len); finally fs.Free; end; end; Procedure StringToFile(const FileName, Str: string);//Inline; var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmcreate); try Len := Length(Str); // fs.Write(Len, SizeOf(Integer)); Raus damit!!!!!! fs.Write(Str[1], Len); finally fs.Free; end; end; Gruß Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Guten Morgen DP!
Das Problem besteht noch: Zitat:
Delphi-Quellcode:
Das bringt mir eine Exception. :gruebel: Procedure StringToFile(const FileName, Str: string);//Inline; var fs: TFileStream; Len: Integer; begin fs := TFileStream.Create(FileName, fmcreate); try Len := Length(Str); fs.Write(Str[1], Len); finally fs.Free; Fileclose(fs.handle); //Das funzt net! end; end; Kann es sein, dass ich beim Lesen z. B. von 900 Files hintereinander mit "FileToString" auch alle Handles holen muss und daher nur ein, nämlich das letzte Handle, schließe? Oder kann es sein, dass ich das Handle beim Lesen noch offen habe? Wie gesagt: Streams sind für mich Neuland. Hat da jemand einen Ansatz zur Lösung? :gruebel: Vielen Dank für Eure Mühe (Mit der Lösung kommt dann auch Delphi Clean 1.2 Beta ohne dem Beta für Euch raus! :zwinker: Beste Grüße Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Guten Morgen.
Du musst an einer anderen Stelle suchen - der Destruktor von TStream gibt das file handle frei. Grüße vom marabu |
Re: FileToString: Wie String zu "StringToFile?"
Guten Morgen marabu,
es kann sein, dass dies (mit dem Handle) der Fehler nicht ist? Im Internet finde ich nirgends ein Fileclose in Verbindung zu den Stream Beispielen. Die Aktionen werden im Regelfall mit Free geschlossen/beendet . Da sich sonst niemand meldet, scheint das Problem mit dem Handle wohl nicht die Ursache und auch ein Fileclose nocht notwendig zu sein. Vielleicht ist ja Deletefile(Filename) der Verursacher und nicht die Streams. Ich kann mir daher keinen Reim machen, wieso die Verzeichnisse via Explorer nicht löschbar sind, wenn mein Programm noch offen ist, aber alle Aktionen korrekt ausgeführt hat. Ich greife auf diese Quellverzeichnisse nur mit StringtoFile und Deletefile darauf zu. :gruebel: Beste Grüße Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Hallo Go2EITS,
hast du vielleicht in deinem Code ein "FindFirst" ohne abschließendes "FindClose" benutzt? Das könnte eine Erklärung für die Fehlermeldung des Explorers sein. Gruß Hawkeye |
Re: FileToString: Wie String zu "StringToFile?"
HAllo,
noch eine Hilfe zur Selbsthilfe: Der ![]() Grüße vom marabu |
Re: FileToString: Wie String zu "StringToFile?"
@marabu
Der Prozessexplorer und der Fileexplorer halfen mir nicht weiter. @Hawkeye219 Da könnte etwas dran sein, weil ich die Schleife vorzeitig verlasse und FindClose wohl nicht mehr aufgerufen wird. Das sehe ich mir mal genauer die Woche an. dazu muss ich mir erst mal einen Testcode "basteln" und etwas Zeit finden. Danke für Eure Hilfe. Ich vermute das FindClose könnte es sein. Ich melde, was es war. Vielen Dank vorerst! :thumb: Beste Grüße Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
Wenn es sich nur um das kopieren dreht,
Was würde gegen ShellExecute aus der unit shellapi und dem Systemprogramm xcopy sprechen ? OffTopic: Das hätte auch den Vorteil das man geöffnete Dateien Kopieren kann...xcopy und ein komandozeilen Zipper ist da Leistungsfähiger als manch eine Bezahldatensicherung... |
Re: FileToString: Wie String zu "StringToFile?"
@Schnellundschmutzig
Auch eine Idee. Danke. :thumb: Go2EITS |
Re: FileToString: Wie String zu "StringToFile?"
der name ist halt programm...
|
Re: FileToString: Wie String zu "StringToFile?"
Hallo,
schon klar dass dieser Thread fast ein Jahr alt ist, aber wenn jemand nach StringToFile sucht landet er schnell hier und hat dann fehlerhaften Code ohne eine Lösung. Deshalb hier kurz das obige Problem: Zitat:
Der Rolf |
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:14 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