AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Datei physikalisch lesen/schreiben ohne den Windows-Cache
Thema durchsuchen
Ansicht
Themen-Optionen

Datei physikalisch lesen/schreiben ohne den Windows-Cache

Ein Thema von devidespe · begonnen am 14. Nov 2007 · letzter Beitrag vom 15. Apr 2010
Antwort Antwort
Seite 1 von 2  1 2      
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#1

Datei physikalisch lesen/schreiben ohne den Windows-Cache

  Alt 14. Nov 2007, 16:12
Hallo,

ich muss auf einem USB-Stick eine Datei erstellen, ihren Inhalt lesen und anschließend miteinander vergleichen. Das habe ich bisher mit normalen Delphi-Funktionen realisiert (Assign, Rewrite, Write, Read, Close). Die Sache hat nur einen Haken: den Windows-Cache. Beim Schreiben auf den USB-Stick meldet mir Windows schneller, dass die Datei geschrieben wurde, als es tatsächlich der Fall ist. Somit kann ich nicht den Zeitpunkt ermitteln, bei dem ich mit dem Lesen beginnen kann.

Um dieses Problem zu umgehen, habe ich gehört, man kann das entsprechende Medium physikalisch öffnen und somit am Windows-Cache "vorbeischreiben".

Bisher habe ich physikalische Laufwerke immer so geöffnet:

Delphi-Quellcode:
Handle := CreateFile(PChar('\\.\PhysicalDrive1'),
                       0,
                       FILE_SHARE_READ or FILE_SHARE_WRITE,
                       nil,
                       OPEN_EXISTING,
                       0,
                       0);
und so

CloseHandle(Handle); wieder geschlossen.

Nun ist mir allerdings schleierhaft, wie ich nach dem Öffnen eine Datei schreiben soll. Es gibt zwar die WriteFile- und ReadFile-Funktionen, die nach dem Aufruf von CreateFile zum Einsatz kommen, aber wie soll ich da eine Datei angeben, die zuvor auch noch erstellt werden muss ?
Devid
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#2

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 16:16
Moin, Moin,
wie wäre es, wenn du statt OPEN_EXISTING mal CREATE_NEW verwendest (F1 auf CreateFile öffnet die recht gute Hilfe) ...
Gruß Ralph
Ralph
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 16:32
Zitat von devidespe:
Um dieses Problem zu umgehen, habe ich gehört, man kann das entsprechende Medium physikalisch öffnen und somit am Windows-Cache "vorbeischreiben".
Das wäre extrem aufwändig, da du so das Dateisystem (FAT16, FAT32, NTFS) selbst unterstützen müsstest.
Lösung: einen Stream verwenden.
Man kann aber nicht direkt einen TFileStream verwenden, sondern muss auf THandleStream ausweichen.
Nur so kann man FILE_FLAG_WRITE_THROUGH angeben.
Delphi-Quellcode:
function CreateUnbuffedFilestream(const filename:string):TStream;
var
   fhandle : THandle;
begin
   fhandle := CreateFile(PChar(filename), GENERIC_READ or GENERIC_WRITE,
   0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, 0);

   if hnd <> INVALID_HANDLE_VALUE then
     result := THandleStream.Create(fhandle)
   else
     result := nil;
end;
Andreas
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 17:08
Mal ne vielleicht doofe Frage:

Wenn ich eine Datei schreibe und die sofort danach wieder lesen will, kann es mir dann aus meiner (Anwender-)Sicht nicht egal sein, ob Caches verwendet werden oder nicht? Caches (zumindest die Schreibcaches bei Datenträgern) sollten transparent sein, es ist (in diesem Fall) Sache des Betriebssystems bzw. der Treiber, dafür zu sorgen.
Wenn ich also eine Datei schreibe und diese dann nicht sofort lesen kann, so ist das meiner Meinung nach ein Mangel des Betriebssystems, der behoben werden sollte.

Oder versteh ich da was falsch?
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 17:11
Ich glaub sein Problem ist, das Windows Erfolf meldet, die daten aber noch nicht zurückgeschrieben wurden. wenn man nun den Stick abzieht, hat man Müll!
Markus Kinzler
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 17:16
Ach so! Gut, das wäre eine Erklärung.

Dann würde ich aber sagen, er sollte lieber prüfen, ob der Stick abgezogen werden kann oder nicht. Dafür ist ja das Dienstprogramm von Windows da, das sich in der Systray einnistet. Wenn man die gleiche Prüfung, die in diesem Programm vorkommt, anwendet, sollte das gewünschte erreicht sein. Bleibt natürlich die Frage, welche das genau ist

Ich finds eben unsauber, ganz auf den Schreibcache zu verzichten. Wenn der Administrator des Systems den Schreibcache anschaltet, dann wird er sich was dabei denken und fände es nicht schön, wenn jedes Programm diese Einstellung ignoriert und durchschreibt. Dann kann er den Cache auch gleich deaktivieren.


Das soll jetzt keine generelle Kritik an der Vorangehensweise sein, ich weiß ja nicht, was das Programm konkret machen soll. Aber prinzipiell finde ich, man sollte zunächst mal versuchen, mit der Konfiguration des Betriebssystem zurechtzukommen, als diese umgehen zu wollen.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#7

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 17:20
Dieses Fehlverhalten bei Wechseldatenträgern hatte Windows nur bei 2000. Bei XP ist der Schreibcache bei Wechseldatenträgern standardmässig deaktiviert. Grundlegend weiss man aber trotzdem nicht, wann er mit dem Schreiben fertig ist, so lange man nicht mit der WebCam die LED des Sticks beobachtet
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#8

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Nov 2007, 17:48
Vielleicht war die gewünschte Aufgabe meiner Anwendung falsch umschrieben.

Eine Teilapplikation soll bspw. die Lesegeschwindigkeit der USB-Medien und auch einer zuvor gebrannten CD ermitteln. Dafür wird die Testdatei eingelesen und die Zeit ermittelt, die dafür benötigt wird. Nehmen wir einmal an, dieser Vorgang dauert für eine 16 MByte Datei 5 Sekunden. Beim zweiten Einlesevorgang nimmt Windows die Datei aber aus seinem Datei-Cache und ich erhalte eine Lesezeit von 0,01 Sekunden - das verfälscht mein Ergebnis auf unerwünschte Art und Weise.

Wenn die CreateFile-Methode bedeutet, dass ich mich mit Dateisystemen und Sektoren rumschlagen muss, ist die Sache den Aufwand nicht Wert.

Mir ist auch keine Windows API-Funktion bekannt, um den Dateisystemcache für bestimmte Laufwerke abzuschalten (was allerdings ohne Neustart erfolgen müsste).

@shmia: Deinen Vorschlag mit dem Stream muss ich ausprobieren, er klingt auch recht vielversprechend. Info folgt dann hier in dieser Diskussion.
Devid
  Mit Zitat antworten Zitat
devidespe

Registriert seit: 7. Sep 2006
Ort: Berlin
434 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Apr 2010, 16:36
Zitat von shmia:
Das wäre extrem aufwändig, da du so das Dateisystem (FAT16, FAT32, NTFS) selbst unterstützen müsstest.
Lösung: einen Stream verwenden.
Man kann aber nicht direkt einen TFileStream verwenden, sondern muss auf THandleStream ausweichen.
Nur so kann man FILE_FLAG_WRITE_THROUGH angeben.
Delphi-Quellcode:
function CreateUnbuffedFilestream(const filename:string):TStream;
var
   fhandle : THandle;
begin
   fhandle := CreateFile(PChar(filename), GENERIC_READ or GENERIC_WRITE,
   0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, 0);

   if hnd <> INVALID_HANDLE_VALUE then
     result := THandleStream.Create(fhandle)
   else
     result := nil;
end;
Hallo shmia,

ich muss nochmal auf Deinen oben genannten Code zurückkommen. Zuerst einmal funktioniert er. Ist es aber möglich, dass das Beschreiben mit FILE_FLAG_WRITE_THROUGH fast 20mal so lange benötigt als ohne? Ich schreibe etwa eine 1 MByte Testdatei auf einen USB-Stick und das braucht fast 2 Minuten mit FILE_FLAG_WRITE_THROUGH, ohne nur wenige Sekunden.

Wenn ich FILE_FLAG_NO_BUFFERING anstatt von FILE_FLAG_WRITE_THROUGH verwende, erhalte ich beim ersten Aufruf von WriteBuffer eine Exception 'Stream-Schreibfehler'.

Es geht mir ja darum, Daten ohne den Windows-Cache zu schreiben. Bei der benötigten Zeit mit FILE_FLAG_WRITE_THROUGH darf ich mir garnicht vorstellen, wie lange eine 100 MByte Datei dauert.
Devid
57 65 72 20 6C 65 73 65 6E 20 6B 61 6E 6E 2C 20 69 73 74 20 6B 6C 61 72 20 69 6D 20 56 6F 72 74 65 69 6C 21
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

Re: Datei physikalisch lesen/schreiben ohne den Windows-Cach

  Alt 14. Apr 2010, 16:51
Lass doch den Cache seine Arbeit machen.
Wenn die Datei geschrieben wurde, dann kann man ja FlushFileBuffers aufrufen:
Delphi-Quellcode:
stream := TFileStream.Create(....
try
  // hier 100MB schreiben

  FlushFileBuffers(stream.Handle);
  // jetzt ist die Datei sicher auf dem Datenträger
finally
  stream.Free;
end;
Bei einem USB-Stick kann es sein, dass dein Programm sekundenlang in FlushFileBuffers festhängt, weil es die Daten auf das physische Medium schreibt.
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:30 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