![]() |
TFileStream: Später nochmal auf unveränderte Datei zugreifen
Moin,
also ich habe folgendes Problem: Eine Datei wird zum Lesen geöffnet, etwa so:
Delphi-Quellcode:
Also natürlich soll die Datei während dem Lesen nicht geändert werden, deswegen fmShareDenyWrite.
TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite)
Nun würde ich aber nach dem Freigeben des Streams fmShareDenyWrite gerne lassen, da ich später nochmal auf die Datei zugreifen muss und diese in der Zwischenzeit nicht geändert werden sollte. Die Frage ist: Geht das irgendwie? Eine andere Möglichkeit wäre natürlich, den Stream irgendwie zu Puffern und einfach im Speicher zu lassen, so dass ich beim nächsten Zugriff nicht mehr auf die Datei, sondern einfach auf den gespeicherten Stream zugriefe, doch da weiß ich irgendwie nicht, wie ich das machen soll, einfach den Stream als Variable speichern und nicht freigeben? Was meint ihr? |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Wenn du den Stream freigibst, dann kann jeder mit dem was machen was er will. Gib ihn nicht frei, dann bleibt er geschützt...
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Ja, das ist schon klar, aber ich brauch ihn halt einmal am Anfang und dann noch etwas später, du meinst also, dass ich den Stream dann erst ganz zum Schluss freigeben soll?
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Wenn du auf die Strasse einen 1000€ Schein legst, und darauf aufpasst (mit Waffe oder so), dann wird der höchstwahrscheinlich nicht gestohlen.
Aber sobald du weggehst - wie hoch ist die Wahrscheinlichkeit, dass der Schein "Beine bekommt und wegläuft"? Richtig - sehr hoch. Was lernen wir daraus? Lasse nichts unbeaufsichtig, wenn du nicht willst, dass es angefasst wird. Und wenn du nicht die ganze Zeit darauf aufpassen willst, dann Sperre es weg (ACL). Nur wo ist der Fehler? |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
:duck: |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Entweder du schliesst den FileStream nicht oder, um das ganze im Code deutlicher zu machen, übergib den FileStream einem MemoryStream. Wobei ein MemoryStreeam auch die Methode LoadFromFile kennt. Es läuft also im Prinzip beides auf das gleiche hinaus. ;)
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Also erstmal danke für eure Antworten!
Ich habe mich nun dazu entschieden, den Stream erst ganz zum Schluss freizugeben. Es sieht folgendermaßen aus: Am Anfang (zu Beginn meiner Prozedur) wird die Datei komplett (Byte für Byte) eingelesen. Dann mache ich etwas und ganz zum Schluss der Prozedur wird die Datei nochmals (Byte für Byte) eingelesen. Ich habe es jetzt so gemacht, dass der Stream über die ganze Prozedur hin geöffnet ist, und eben erst ganz zum Schluss freigegeben wird, ist denke ich auch die einfachste Methode. Die Frage ist nur, wenn ich das in einen MemoryStream speichere, ist dann das zweite einlesen ggf. schneller? |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Wenn du die Datei per LoadFromFile in einen Memorystream lädst, hast du die gesamte Datei [u]im Speicher[i]. Damit dauert das erste einlesen also um einiges länger, aber dafür sind alle anderen Operationen auf die Daten fast in Nullzeit machbar - und deine Daten werden nicht einfach so von anderen Programmen verändert, während deine Prozedur durchläuft.
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Also nehmen wir mal an, dass Festplatten schneller wären als der Hauptspeicher. Was würde das bedeuten?
1. Ich hätte die Festplatten schon längst verbannt. 2. Ich hätte 2000 TB Hauptspeicher 3. Mein PC würde rund um die Uhr laufen; ich hätte Windows durch Linux ersetzt (wegen den Abstürzen); würde eine riesige Stromrechnung haben; und nicht schlafen können, weil die Kühler so laut sind 4. Ich würde jedesmal aus dem Fenster springen (2.Stock), wenn mein PC abstürzt, weil dann alle Daten verloren sind (aktueller RAM ist noch flüchtiger Speicher) Ja, Hauptspeicher ist (in den allermeisten Fällen) schneller als Festplattenspeicher - dafür aber kostbarer (da weniger vorhanden). Man muss jedoch beachten, dass Wasser durch schmale Röhren länger braucht, um ans Ziel zu kommen, als durch breite Rohre. Also lieber nicht Wass..äh Daten byteweise in den Speicher schaufeln, sondern in größeren Stücken ("Wieviel darf's denn sein?"). Dann klappts auch mit der Geschwindigkeit. P.S. Macht dir nichts aus dem Stil meiner Antwort - ich hab zuviel ![]() |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
o_O ich stelle grad fest, dass ist mit TMemoryStream ist nicht nur schneller, das ist viel schneller.
Danke für den Tipp :thumb: Scheint so, dass das Einlesen Byte für Byte länger brauch, als TMemoryStream.LoadFromFile(). Z.B. bei einer 1,5 MB großen Datei hat die erste Variante schon ein paar Sekunden gedauert, mit TMemoryStream dagegen gehts so schnell, da kann man gar nicht gucken :shock: Danke nochmals! //Edit: Zitat:
Also bei meinem Beispiel einer 1,5 MB großen Datei dürfte das bei 1 GB RAM kein Problem sein, oder? Wobei das natürlich bei Dateien jeder beliebigen Größe optimal gehen sollte... |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Wenn deine Prozedur die Datei byteweise einliest und verarbeitet, mach do sowas:
Delphi-Quellcode:
Damit dürfte immer alles recht fix gehen, bei minimaler Speicherbelastung.
var
fs: TFileStream; buffer: array[0..32767] of Byte; byteCount, i: Integer; begin fs := ... ; repeat byteCount := fs.Read(buffer, sizeof(buffer)); for i := 0 to byteCount do verarbeite buffer[i]; until byteCount = 0; end; |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
OK, das sieht ganz gut aus, für die 32767 dann am besten eine Konstante nehmen, so kann man es leicht ändern.
Kleiner Schönheitsfehler: In der For-Schleife muss es byteCount-1 heißen. Könnte man das Ermitteln von sizeof(buffer) nicht auch durch das Verwenden einer Konstante performanter machen? Ist jetzt vielleicht ein wenig OT, aber ich muss die Datei eigentlich Bitweise lesen, aber der Buffer geht nicht zufällig auch mit einem array of Boolean? Ich habe es halt bisher so gemacht, dass ich das eingelesene Byte in einer weiteren For-Schleife jeweils um i nach rechts Shifte und dann eben mit and 1 ... |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
Zitat:
Zitat:
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Gut, danke nochmal an alle, werde das dann mal soweit umsetzen.
:-D |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Wenn du unterhalb von (RAM+Auslagerungsdatei)-Größe bleibst, sollte es keine Probleme geben. Allerdings solltest du beachten, daß andere Anwendungen laufen und das OS selber auch RAM braucht - zieh also noch einen großen Brocken davon ab und dur bist immer auf der sicheren Seite. Ab Windows 2000 solltest du bspw. ohne weiteres 64 MiB laden können. Soweit ich weiß benutzt das ja auch MMFs und wenn die Implementierung korrekt ist, wird sich der Memory-Manager drum kümmern, daß die Daten im Speicher verfügbar sind (wobei Speicher nicht gleichzusetzen ist mir phys. RAM - schließlich reden wir über Usermode) ;)
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
welche Bits darstellten. Aber schon damals hat man mehrere Bits zusammengefasst. Die Frage kommt sehr oft im Forum. |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Danke nochmals für eure Antworten :)
Zitat:
Was ist MMF? Ich habe irgendwie immernoch folgendes Problem: Für kleinere Textdateien ist die von Dax vorgeschlagene Buffergröße von 32 KB vielleicht ganz gut, aber wenn ich eine mehrere MB große Datei habe, wäre eine Buffergröße von 64 MB nicht schlecht (wie Olli sagt, dürfte das kein Problem sein). Allerdings wenn ich dann bei dem 64 MB großen Buffer nur eine kleine Textdatei einlese mit ein paar KB, dann belege ich ja trotzdem die 64 MB im Speicher -> nicht so optimal. Was empfehlt ihr? Vielleicht doch wieder TMemoryStream verwenden? |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
Zitat:
|
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Hi,
auch, wenn es nicht das eigentliche Problem betrifft, jedoch: Zitat:
Delphi-Quellcode:
Zumindest sagt meine OH, dass der zweite Parameter nur unter Linux funktioniert und für die Rechte steht (womit aber das gemeint ist, was sich per chmod ändern lässt). Unter Windows wird er ignoriert.
TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite)
Mfg FAlter |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
Also angenommen ich lade eine 4 GB große Datei in einen TMemoryStream und habe einen RAM von 1 GB. Passt das dann noch irgendwie in die Auslagerungsdatei (wobei andere Anwendungen ja auch noch RAM verbrauchen), oder was macht TMemoryStream dann? Gibts dann ne Exception, wenn das zu groß wird für einen MemoryStream? |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
Relevant ist, wie gesagt, die Größe des RAMs und der Auslagerungsdatei zusammen, minus das was vom OS selber und anderen Anwendungen gebraucht wird. |
Re: TFileStream: Später nochmal auf unveränderte Datei zugre
Zitat:
@FAlter: also ehrlich gesagt bin ich da überfragt :pale: Aber ich seh auch grad, dass in der Hilfe steht, dass man es mit or verknüpfen soll. Wobei es bei TFileStream diese beiden Konstruktoren gibt :gruebel:
Delphi-Quellcode:
constructor Create(const AFileName: string; Mode: Word); overload;
constructor Create(const AFileName: string; Mode: Word; Rights: Cardinal); overload; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:39 Uhr. |
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