![]() |
Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Hallo,
ich muss eine größere Datei mehrfach von Position A zu Position B kopieren. Position A ist hier eine CD und Position B ein temporäres Verzeichnis auf der Festplatte. Ab dem 2. Versuch spring allerdings der Windows-Cache ein und ich kann die CD quasi herausnehmen, obwohl der Vorgang weiterläuft. Deswegen muss ich diesen Vorgang ohne den Windows-Cache durchführen. Bisher habe ich folgendes zum Öffnen des Laufwerks:
Delphi-Quellcode:
Wie kann ich jetzt eigentlich die Kopieraktion implementieren? Muss das über BlockRead/BlockWrite mit einem Puffer geschehen?
function KopiereDatei(Laufwerk: Char; Datei : string) : Boolean;
var handle : THandle; begin Result:=False; Handle:=CreateFile(PChar('\\.\' + Laufwerk + ':'), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING, 0); if Handle <> INVALID_HANDLE_VALUE then begin {hier müsste der Kopiervorgang starten} end; CloseHandle(Handle); end; begin if KopiereDatei('D', 'TESTFILE.DAT') = true then ShowMessage('Datei erfolgreich kopiert.') else ShowMessage('Fehler beim Kopieren der Datei.'); end; Es gibt ja auch noch das Attribut FILE_FLAG_WRITE_THROUGH. Ist dieses als Alternative zu FILE_FLAG_NO_BUFFERING zu verwenden, oder kann man das zusätzlich machen? |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
![]() |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Warum öffnest du das Laufwerk? Du musst die zu kopierende Datei mit entsprechenden Flags öffnen.
|
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Hallo devidespe, ich hoffe es ist noch nicht zu spät für eine Warnung!
Wenn du hier
Delphi-Quellcode:
mit WriteFile zu schreiben anfängst, zerstörst du dir MBR und oder MFT!!!if Handle <> INVALID_HANDLE_VALUE then begin {hier müsste der Kopiervorgang starten} end; Du wirst dann eine Neupartitionierung und Formatierung, der Festplatte nicht verhindern können. lg. |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
|
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zum Glück habe ich mir noch nicht den MBR zerstört. Danke für die Warnung.
Zitat:
|
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Luckie wollte sagen, dass
Delphi-Quellcode:
dir ein Handle auf das Laufwerk, nicht aber auf die Datei gibt, die du ja eigentlich haben willst. Deswegen vermutlich auch die panische Reaktion des Vorposters.
Handle:=CreateFile(PChar('\\.\' + Laufwerk + ':'), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING, 0);
Zitat:
Zitat:
![]() ![]() Was ich mich frage: Zu was soll das eigentlich gut sein? Wenn es dir um einen Benchmark geht, oder du prüfen möchtest, ob die CD in Ordnung ist, würde ich eher zu SPTI greifen... |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
SPTI kann ich mir anschauen, das kannte ich noch nicht. Ansonsten denke ich, dass ReadFile/WriteFile ebenfalls ein Schritt in die korrekte Richtung ist. |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
Ansonsten kann man aber auch einfach die Richtlinien für den entsprechenden Nutzer anpassen, siehe: ![]() CreateFile funktioniert natürlich auch... Wenn du noch ein bisschen weiter gucken möchtest, und C mächtig bist, kannst du hier mal schauen: ![]() Und dann gibts ja auch noch Freeburner und die TISOLib, beides eher zum Ausschlachten. |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Danke Daniel G für die Links.
Im Grunde suche ich allerdings eine Lösung, die sich nicht nur für CD-Laufwerke, sondern gleichermaßen für Festplatten verwenden lässt. Soll heißen, dass eine größere temporäre Datei von einem Temp-Verzeichnis in ein anderes Temp-Verzeichnis kopiert werden soll. Da scheint mir CreateFile die universelle Lösung zu sein. Ich muss nur noch herausbekommen, wie ich das auf Dateien anwende, da mein Beispiel im ersten Post ja nur ein Handle für das Laufwerk erzeugt. |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
und jetzt rate mal, womit man ein Dateihandle bekommt. :angel: |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
Ich hatte noch überlegt, mit SHFileOperation zu arbeiten. Allerdings erlauben die Flags keine Umgehung des Windows-Caches. |
Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Du öffnest einfach beide Dateien
einmal mir Leserechten und FILE_FLAG_NO_BUFFERING und nochmal mit Schreibrechten und (FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING) und dann ließt du einfach mit ReadFile in einem Puffer und schreibst diesen in die andere Datei. Vergiß aber nicht, es können nur ganze Sektoren gelesen und geschrieben werden. Tipp: schau dir mal die Codes meines alten ![]() PS: du kannst auch mal mit hiermit spielen Leserechte und FILE_FLAG_SEQUENTIAL_SCAN Schreibrechte und (FILE_FLAG_SEQUENTIAL_SCAN or FILE_FLAG_WRITE_THROUGH) genaueres zu den Parametern siehe ![]() PSS: da es um Temp-Dateien geht, kann ich auch noch FILE_ATTRIBUTE_TEMPORARY empfehlen. |
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Es ist ja schon ein paar Tage her, aber vielleicht ist mittlerweile
![]() Ich benutze gerade die Umgehung des File Caches für den Vergleich von zwei Dateien. Das Codegerüst sieht ungefähr so aus:
Delphi-Quellcode:
(Der Wert der Konstante K256 stammt übrigens von
var i:integer;
DatnameQuelle,DatnameZiel:string; HQuelle,HZiel:THandle; BufQuelle,BufZiel:TBytes; AnzBytesQ,AnzBytesZ:Cardinal; const K256 = 256 * 1024; HQuelle := CreateFile(PChar(DatnameQuelle), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); HZiel := CreateFile(PChar(DatnameZiel), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); Try If (HQuelle <> INVALID_HANDLE_VALUE) and (HZiel <> INVALID_HANDLE_VALUE) then begin Repeat ReadFile(HQuelle, BufQuelle[0], K256, AnzBytesQ, nil); ReadFile(HZiel, BufZiel[0], K256, AnzBytesZ, nil); If (AnzBytesQ <> AnzBytesZ) or not CompareMem(BufQuelle,BufZiel,K256) then begin break; end; until AnzBytesQ < K256; end; Finally FileClose(HQuelle); FileClose(HZiel); End; ![]() Ich frage mich aber, ist das eigentlich sinnvoll, den Cache hier zu umgehen? In meinem Szenario werden die Dateien nicht nochmal eingelesen, der Cache würde also keinen Vorteil bringen. |
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Hier stand Quatsch.
|
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
|
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
Delphi-Quellcode:
umgangen wird.
FILE_FLAG_NO_BUFFERING
|
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Sorry @Benmik, kleines Missverständnis.
Ich hatte auf LTE5 geantwortet, der etwas von 'hier fehlt ein WriteFile für HZiel' gemurmelt hatte ;) Schade wenn Antworten gelöscht werden, so geht natürlich der Kontext für nachfolgende Leser komplett verloren. Zu Deinem Problem kann ich leider nix beitragen |
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Zitat:
Also ohne Cache ist es "meißtens" besser und du mußt das durch optimieren der restlichen Funktionen verbessern, Also muß eine Datei wirklich mehrmals komplett gelesen werden? (z.B. erstmal Haschen und für den Erstvergleich zweier Dateien erstmal die Hashs verwenden, anstatt jedesmal wieder auf den Dateiinhalt zuzugreifen) PS: Die Dateisystemtreiber arbeiten mit 64 KB als Transferpuffer (rate mal warum im Speicher zufällig der erste Speicherblok von $00000000 bis $0000FFFF gespert ist und wofür der z.B. verwendet wird). Ja, Nonbuffered muß man mit dem Mehrfachen der Sektorgröße abeiten, da nur komplette Sektoren gelesen und vorallem geschrieben werden können. Und um die IOPs zu optimieren nimmt man dann ein Mehrfaches sämtlicher durchlaufener Puffer/Caches. ![]() |
AW: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
Hallo himitsu, vielen Dank. Dann scheint das alles doch in die richtige Richtung zu gehen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:24 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