Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING) (https://www.delphipraxis.net/143985-datei-kopieren-ohne-cache-file_flag_no_buffering.html)

devidespe 27. Nov 2009 12:09


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:
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;
Wie kann ich jetzt eigentlich die Kopieraktion implementieren? Muss das über BlockRead/BlockWrite mit einem Puffer geschehen?

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?

Mithrandir 27. Nov 2009 12:19

Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
 
Zitat:

Zitat von devidespe
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?

Beitrag dazu in der Knowledge Base

Luckie 27. Nov 2009 12:27

Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
 
Warum öffnest du das Laufwerk? Du musst die zu kopierende Datei mit entsprechenden Flags öffnen.

uoeb7gp 27. Nov 2009 22:52

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:
 
if Handle <> INVALID_HANDLE_VALUE then
  begin
    {hier müsste der Kopiervorgang starten}
  end;
mit WriteFile zu schreiben anfängst, zerstörst du dir MBR und oder MFT!!!

Du wirst dann eine Neupartitionierung und Formatierung, der Festplatte nicht verhindern können.

lg.

Mithrandir 28. Nov 2009 08:25

Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
 
Zitat:

Zitat von uoeb7gp
mit WriteFile zu schreiben anfängst, zerstörst du dir MBR und oder MFT!!!

Das müsstest du vielleicht mal genauer ausführen...

devidespe 28. Nov 2009 09:01

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:

Zitat von Luckie
Warum öffnest du das Laufwerk? Du musst die zu kopierende Datei mit entsprechenden Flags öffnen.

Mit normalen Dateifunktionen wie Assign, BlockRead/BlokWrite bzw. auch über Streams kann ich nicht arbeiten, da sie den Windows Cache verwenden. Existiert denn überhaupt noch eine andere Möglichkeit, um dies ohne den Windows Cache zu erledigen?

Mithrandir 28. Nov 2009 09:11

Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
 
Luckie wollte sagen, dass

Delphi-Quellcode:
Handle:=CreateFile(PChar('\\.\' + Laufwerk + ':'), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING, 0);
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.

Zitat:

Mit normalen Dateifunktionen wie Assign, BlockRead/BlokWrite bzw. auch über Streams kann ich nicht arbeiten, da sie den Windows Cache verwenden.
Das ist - mit Verlaub - Schwachsinn. Wenn du die Funktionen nutzt, die Delphi bereitstellt, um mit dem Handle von CreateFile zu arbeiten, dann wird Delphi nicht das Handle spontan ändern und das FILE_FLAG_NO_BUFFERING herausnehmen.

Zitat:

Existiert denn überhaupt noch eine andere Möglichkeit, um dies ohne den Windows Cache zu erledigen?
Siehe Absatz vorher. Ansonsten:
MSDN-Library durchsuchenReadFile,MSDN-Library durchsuchenWriteFile

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...

devidespe 28. Nov 2009 09:24

Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
 
Zitat:

Zitat von Daniel G
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...

Es geht in der Tat um eine Art BurnIn-Belastungstest, bei dem das CD-Laufwerk gestresst werden soll. Dies kann aber nur geschehen, wenn konstant Daten vom Laufwerk gelesen werden und nicht etwa der Windows-Cache bemüht wird.

SPTI kann ich mir anschauen, das kannte ich noch nicht. Ansonsten denke ich, dass ReadFile/WriteFile ebenfalls ein Schritt in die korrekte Richtung ist.

Mithrandir 28. Nov 2009 10:32

Re: Datei kopieren ohne Cache (FILE_FLAG_NO_BUFFERING)
 
Zitat:

Zitat von devidespe
Es geht in der Tat um eine Art BurnIn-Belastungstest, bei dem das CD-Laufwerk gestresst werden soll. Dies kann aber nur geschehen, wenn konstant Daten vom Laufwerk gelesen werden und nicht etwa der Windows-Cache bemüht wird.

SPTI kann ich mir anschauen, das kannte ich noch nicht.

Jupp, stimmt. Dann würde ich aber die Daten, die ja eigentlich nicht gebraucht werden, in einen temporären Speicher schreiben, der bei jedem neuen Auslesen wieder überschrieben wird. So spart man sich das vollschreiben der Festplatte. Bedenke aber, dass man zum Nutzen von SPTI Adminrechte benötigt. Ich bin mir hundertprozentig sicher, es gab eine Möglichkeit, wie man das im Programmcode verhindern konnte und SPTI ohne Adminrechte nutzen konnte. Ich finde nur den Link nicht mehr... :wall:

Ansonsten kann man aber auch einfach die Richtlinien für den entsprechenden Nutzer anpassen, siehe: ImgBurn FAQ

CreateFile funktioniert natürlich auch... Wenn du noch ein bisschen weiter gucken möchtest, und C mächtig bist, kannst du hier mal schauen: http://www.cdtool.pwp.blueyonder.co.uk/workshop.htm

Und dann gibts ja auch noch Freeburner und die TISOLib, beides eher zum Ausschlachten.

devidespe 1. Dez 2009 09:34

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:30 Uhr.
Seite 1 von 2  1 2      

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