Ich suche nach einer Möglichkeit, eine Datei asynchron und effizient zu erweitern.
In einem Unterstützungsdokument erscheint Asynchronous Disk I / O unter Windows NT, Windows als synchron 2000 und Windows XP sagten:
HINWEIS: Anwendungen können den zuvor erwähnten Schreibvorgang ausführen asynchron durch Ändern der gültigen Datenlänge der Datei mit die SetFileValidData-Funktion und dann ein WriteFile ausgeben.
in MSDN ist SetFileValidData
eine Funktion für Sets the valid data length of the specified file
.
Aber ich verstehe immer noch nicht, was die "gültigen Daten" sind, was ist der Unterschied zwischen ihnen und der Größe der Datei?
Ich kann SetFilePointerEx
und SetEndOfFile
verwenden, um die Dateigröße zu vergrößern, aber wie funktioniert das mit SetFileValidData
?
SetFileValidData
kann kein Argument eingeben, das größer als die Dateigröße ist. Was ist in diesem Fall die lebende Bedeutung von SetFileValidData
?
Wenn Sie SetEndOfFile
verwenden, um die Länge einer Datei zu erhöhen, ändert sich die logische Dateilänge und der erforderliche Speicherplatz wird zugewiesen, aber tatsächlich werden keine Daten physisch in die Plattensektoren geschrieben, die dem neuen Teil der Datei entsprechen. Die gültige Datenlänge bleibt die gleiche wie zuvor.
Dies bedeutet, dass Sie SetEndOfFile
verwenden können, um eine Datei sehr schnell sehr groß zu machen, und wenn Sie aus dem neuen Teil der Datei lesen, erhalten Sie nur Nullen. Die gültige Datenlänge erhöht sich, wenn Sie tatsächliche Daten in den neuen Teil der Datei schreiben.
Das ist in Ordnung, wenn Sie nur Speicherplatz reservieren möchten und dann Daten sequenziell in die Datei schreiben. Aber wenn Sie die Datei sehr groß machen und sofort Daten nahe dem Ende davon schreiben, müssen Nullen in den neuen Teil der Datei geschrieben werden, was lange dauern wird. Wenn die Datei keine Nullen enthalten soll, können Sie SetFileValidData
verwenden, um diesen Schritt zu überspringen. Der neue Teil der Datei enthält dann zufällige Daten von zuvor gelöschten Dateien.
Bitte beachten Sie, dass setendoffile keine Nullen in zugewiesene Sektoren auf der Festplatte schreibt, sondern nur die Leerzeichen in MFT-Datensätzen und dann die Space-Bitmap des gesamten Dateisystems aktualisiert. Aber OS, oder FS, wird die gültige / logische Dateilänge in seinem MFT-Datensatz aufzeichnen, wenn Sie es vergrößern, von 1 GB auf 2 GB, dann sollte die 1GB-Datei nur Nullen sein, aber FS wird die Nullen nicht auf Festplatten verteilen Beziehen Sie sich auf die gültige Länge dieser Datei, um zu wissen, dass die 1GB Nullen sein sollte, wenn Sie versuchen, auf diesen vergrößerten 1GB Teil zuzugreifen, wird Zeore direkt im RAM und dann Feedback zu Ihrer Anwendung gefüllt. Wenn Sie jedoch auf ein Byte in diesem 1 GB-Teil zugreifen, muss der FS mit Nullen vom ursprünglichen 1 GB-Offset bis zum aktuellen Zeiger gefüllt werden, den Ihre Anwendung schreiben soll, nicht aber die anderen Bytes von der aktuellen Position bis zum Ende der Datei, und unterdessen zeichnet die gültige / logische Länge von 0 bis zum aktuellen Standort, die physische Größe und zugewiesene Größe ist immer noch 2 GB. Aber wenn Sie setfilevaliddata verwenden, wird FS die gültige Länge direkt auf 2GB setzen, und wird sich nicht darum kümmern, irgendwelche Nullen zu füllen, egal wo Sie schreiben, es schreibt nur, aber egal wo Sie lesen, können Sie einige Daten auslesen generiert von anderen Anwendungen.
Stimmen Sie der Antwort von Harry Johnston zu, und von der Praxis her gesehen hat SetFileValidData zwar einen Leistungsvorteil, weil es keine Nullen schreiben muss, aber es hat Auswirkungen auf die Sicherheit, da die Datei Daten von anderen gelöschten Dateien enthalten kann. Daher ist eine spezielle Berechtigung, SE_MANAGE_VOLUME_NAME, erforderlich, wie in MSDN erwähnt: Ссылка
Der Grund dafür ist, dass die Verwendung von SetFileValidData die gelöschten Daten eines anderen Benutzers in der Ansicht dieser bestimmten Datei verfügbar machen kann, wenn das Benutzerkonto des ausgeführten Programms diese Berechtigung nicht besitzt. Daher sind normale Benutzer (Nicht-Administratoren) nicht erlaubt das zu tun. Selbst für privilegierte Benutzer müssen sie immer noch ACL (Access Control Lists) im Dateisystem verwenden, um diese Datei zu schützen, so dass sie nicht mit nicht-privilegierten Benutzern geteilt wird.
Es scheint, dass SenEndofFile
nicht wirklich reservierten Speicherplatz für die Zieldatei reserviert, SetFileValidData
ist verantwortlich für den Job.
Sie können die SetFileValidData-Funktion verwenden, um unter sehr speziellen Umständen große Dateien zu erstellen, damit die Leistung der nachfolgenden Datei-I / O besser sein kann als bei anderen Methoden. Insbesondere wenn der erweiterte Teil der Datei groß ist und zufällig geschrieben wird, z. B. in einem Datenbanktyp der Anwendung, ist die zum Erweitern und Schreiben der Datei benötigte Zeit schneller als das Verwenden von SetEndOfFile und das zufällige Schreiben.
Wenn SetEndOfFile
wirklich Speicherplatz reserviert, dann wird SetFileValidData
beim zufälligen Schreiben nichts besser machen als SetEndOfFile
. So kann SetEndOfFile
nur eine Sparse-Datei mit Löchern erstellen, während SetFileValidData
die tatsächliche Zuweisung übernimmt.