Freigeben über


Erstellen und Öffnen von Dateien

Die Funktion CreateFile kann eine neue Datei erstellen oder eine vorhandene Datei öffnen. Sie müssen den Dateinamen, die Erstellungsanweisungen und andere Attribute angeben. Wenn eine Anwendung eine neue Datei erstellt, fügt das Betriebssystem sie dem angegebenen Verzeichnis hinzu.

Das Betriebssystem weist jeder Datei, die mit CreateFile geöffnet oder erstellt wird, einen eindeutigen Bezeichner zu, der Handle genannt wird. Eine Anwendung kann dieses Handle mit Funktionen verwenden, die von der Datei lesen, in sie schreiben und sie beschreiben. Es ist so lange gültig, bis alle Verweise auf dieses Handle geschlossen werden. Wenn eine Anwendung startet, erbt sie alle offenen Handles von dem Prozess, der sie gestartet hat, wenn die Handles als vererbbar erstellt wurden.

Eine Anwendung sollte den Wert des von CreateFile zurückgegebenen Handles überprüfen, bevor sie versucht, das Handle für den Zugriff auf die Datei zu verwenden. Wenn ein Fehler auftritt, wird der Wert des Handles INVALID_HANDLE_VALUE sein und die Anwendung kann die Funktion GetLastError für erweiterte Fehlerinformationen verwenden.

Wenn eine Anwendung CreateFile verwendet, muss sie mit dem Parameter dwDesiredAccess angeben, ob sie aus der Datei lesen, in die Datei schreiben, sowohl lesen als auch schreiben oder keines von beiden will. Dies wird als Anforderung eines Zugriffsmodus bezeichnet. Die Anwendung muss auch den Parameter dwCreationDisposition verwenden, um anzugeben, welche Aktion ausgeführt werden soll, wenn die Datei bereits existiert, was als Erstellungsdisposition bezeichnet wird. Eine Anwendung kann z. B. CreateFile mit dwCreationDisposition auf CREATE_ALWAYS festgelegt aufrufen, um immer eine neue Datei zu erstellen, auch wenn eine Datei mit demselben Namen bereits existiert (und damit die bestehende Datei zu überschreiben). Ob dies erfolgreich ist oder nicht, hängt von Faktoren wie den Attributen der bisherigen Datei und den Sicherheitseinstellungen ab (siehe die folgenden Abschnitte für weitere Informationen).

Eine Anwendung verwendet CreateFile auch, um anzugeben, ob sie die Datei zum Lesen, zum Schreiben, für beides oder für keines von beiden freigeben möchte. Dies wird als Freigabemodus bezeichnet. Eine geöffnete Datei, die nicht freigegeben ist (dwShareMode auf Null festgelegt), kann nicht wieder geöffnet werden, weder von der Anwendung, die sie geöffnet hat, noch von einer anderen Anwendung, bis ihr Handle geschlossen wurde. Dies wird auch als exklusiver Zugriff bezeichnet.

Wenn ein Prozess mit CreateFile versucht, eine Datei zu öffnen, die bereits in einem Freigabemodus (dwShareMode auf einen gültigen Wert ungleich Null festgelegt) geöffnet wurde, vergleicht das System die angeforderten Zugriffs- und Freigabemodi mit denen, die beim Öffnen der Datei festgelegt wurden. Wenn Sie einen Zugriffs- oder Freigabemodus angeben, der im Widerspruch zu den im vorherigen Aufruf angegebenen Modi steht, schlägt CreateFile fehl.

Die folgende Tabelle zeigt die gültigen Kombinationen von zwei Aufrufen von CreateFile mit verschiedenen Zugriffs- und Freigabemodi (dwDesiredAccess bzw. dwShareMode). Es spielt keine Rolle, in welcher Reihenfolge die CreateFile-Aufrufe gemacht werden. Nachfolgende Geschäftsvorgänge mit den einzelnen Datei-Handles werden jedoch weiterhin durch die aktuellen Zugriffs- und Freigabemodi eingeschränkt, die mit dem jeweiligen Datei-Handle verbunden sind.

Erster Aufruf von CreateFile Gültige zweite Aufrufe von CreateFile
GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ FILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE

Zusätzlich zu den standardmäßigen Dateiattributen können Sie auch Sicherheitsattribute angeben, indem Sie einen Zeiger auf eine SECURITY_ATTRIBUTES-Struktur als vierten Parameter von CreateFile angeben. Allerdings muss das zugrunde liegende Dateisystem die Sicherheitsmerkmale unterstützen, damit dies eine Wirkung hat (das NTFS-Dateisystem unterstützt dies beispielsweise, die verschiedenen FAT-Dateisysteme jedoch nicht). Weitere Informationen über Sicherheitsattribute finden Sie unter Zugriffssteuerung.

Eine Anwendung, die eine neue Datei erstellt, kann einen optionalen Handle auf eine Vorlagendatei übergeben, aus der CreateFile die Dateiattribute und erweiterten Attribute für die Erstellung der neuen Datei übernimmt.

CreateFile-Szenarien

Es gibt mehrere grundlegende Szenarien für den Zugriff auf eine Datei mit der Funktion CreateFile. Diese sind wie folgt zusammengefasst:

  • Erstellen einer neuen Datei, wenn eine Datei mit diesem Namen noch nicht existiert.
  • Erstellen einer neuen Datei, auch wenn eine Datei mit demselben Namen bereits existiert, wobei die Daten gelöscht werden und die Datei leer startet.
  • Öffnen einer vorhandenen Datei nur dann, wenn sie existiert, und zwar nur intakt.
  • Öffnen einer vorhandenen Datei nur, wenn sie existiert, wobei die Daten abgeschnitten werden, damit sie leer ist.
  • Öffnen einer Datei immer: So wie sie ist, wenn sie existiert, Erstellen einer neuen Datei, wenn sie nicht existiert.

Diese Szenarien werden durch die richtige Verwendung des Parameters dwCreationDisposition gesteuert. Nachfolgend finden Sie eine Aufschlüsselung, wie diese Szenarien den Werten für diesen Parameter zugeordnet werden und was passiert, wenn sie verwendet werden.

Beim Erstellen oder Öffnen einer neuen Datei, wenn eine Datei mit diesem Namen noch nicht existiert (dwCreationDisposition entweder auf CREATE_NEW, CREATE_ALWAYS oder OPEN_ALWAYS festgelegt), führt die Funktion CreateFile die folgenden Aktionen aus:

  • Kombiniert die durch dwFlagsAndAttributes angegebenen Dateiattribute und Flags mit FILE_ATTRIBUTE_ARCHIVE.
  • Legt die Dateilänge auf Null fest.
  • Kopiert die von der Vorlagendatei gelieferten erweiterten Attribute in die neue Datei, wenn der Parameter hTemplateFile angegeben ist (dies setzt alle FILE_ATTRIBUTE_* Flags außer Kraft, die zuvor angegeben wurden).
  • Legt das durch das bInheritHandle-Mitglied angegebene Flag und den durch das lpSecurityDescriptor-Mitglied des lpSecurityAttributes-Parameters (SECURITY_ATTRIBUTES-Struktur) angegebenen Sicherheitsdeskriptor fest, sofern dieser geliefert wird.

Beim Erstellen einer neuen Datei, auch wenn bereits eine Datei mit demselben Namen existiert (dwCreationDisposition auf CREATE_ALWAYS festgelegt), führt die Funktion CreateFile die folgenden Aktionen aus:

  • Prüft die aktuellen Dateiattribute und Sicherheitseinstellungen auf Schreibzugriff und verweigert diesen, wenn er verweigert wird.
  • Kombiniert die durch dwFlagsAndAttributes angegebenen Dateiattribute und Flags mit FILE_ATTRIBUTE_ARCHIVE und den vorhandenen Dateiattributen.
  • Legt die Dateilänge auf Null fest (d. h. alle Daten, die in der Datei waren, sind nicht mehr verfügbar, und die Datei ist leer).
  • Kopiert die von der Vorlagendatei gelieferten erweiterten Attribute in die neue Datei, wenn der Parameter hTemplateFile angegeben ist (dies setzt alle FILE_ATTRIBUTE_* Flags außer Kraft, die zuvor angegeben wurden).
  • Legt das Flag für die Vererbung fest, das durch das bInheritHandle-Mitglied des lpSecurityAttributes-Parameters (SECURITY_ATTRIBUTES-Struktur) angegeben wird, falls geliefert, ignoriert aber das lpSecurityDescriptor-Mitglied der SECURITY_ATTRIBUTES-Struktur.
  • Wenn ansonsten erfolgreich (d. h. CreateFile gibt ein gültiges Handle zurück), liefert der Aufruf von GetLastError den Code ERROR_ALREADY_EXISTS, obwohl es sich in diesem speziellen Anwendungsfall eigentlich nicht um einen Fehler handelt (wenn Sie beabsichtigten, eine „neue“ (leere) Datei anstelle der bestehenden zu erstellen).

Beim Öffnen einer bestehenden Datei (dwCreationDisposition entweder auf OPEN_EXISTING, OPEN_ALWAYS oder TRUNCATE_EXISTING festgelegt) führt die Funktion CreateFile die folgenden Aktionen durch:

  • Prüft die aktuellen Dateiattribute und Sicherheitseinstellungen für den angefragten Zugriff und verweigert ihn, wenn er verweigert wird.
  • Kombiniert die Dateiflags (FILE_FLAG_*), die durch dwFlagsAndAttributes angegeben wurden, mit den vorhandenen Dateiattributen und ignoriert alle Dateiattribute (FILE_ATTRIBUTE_*), die durch dwFlagsAndAttributes angegeben wurden.
  • Setzt die Dateilänge nur dann auf Null, wenn dwCreationDisposition auf TRUNCATE_EXISTING festgelegt ist. Andernfalls wird die aktuelle Dateilänge beibehalten, und die Datei wird so geöffnet, wie sie ist.
  • Ignoriert den Parameter hTemplateFile.
  • Legt das Flag für die Vererbung fest, das durch das bInheritHandle-Mitglied des lpSecurityAttributes-Parameters (SECURITY_ATTRIBUTES-Struktur) angegeben wird, falls geliefert, ignoriert aber das lpSecurityDescriptor-Mitglied der SECURITY_ATTRIBUTES-Struktur.

Dateiattribute und Verzeichnisse

Dateiattribute sind Teil der Metadaten, die mit einer Datei oder einem Verzeichnis verknüpft sind. Sie haben jeweils ihren eigenen Zweck und Regeln, wie sie festgelegt und geändert werden können. Einige dieser Attribute gelten nur für Dateien, andere nur für Verzeichnisse. Das Attribut FILE_ATTRIBUTE_DIRECTORY gilt zum Beispiel nur für Verzeichnisse: Es wird vom Dateisystem verwendet, um festzustellen, ob ein Objekt auf dem Datenträger ein Verzeichnis ist, kann aber für ein bestehendes Dateisystemobjekt nicht geändert werden.

Einige Dateiattribute können für ein Verzeichnis festgelegt werden, haben aber nur Bedeutung für Dateien, die in diesem Verzeichnis erstellt werden, und dienen als Standardattribute. So kann z. B. FILE_ATTRIBUTE_COMPRESSED für ein Verzeichnisobjekt festgelegt werden, aber da das Verzeichnisobjekt selbst keine Daten enthält, wird es nicht wirklich komprimiert; Verzeichnisse, die mit diesem Attribut gekennzeichnet sind, weisen das Dateisystem jedoch an, alle neuen Dateien, die diesem Verzeichnis hinzugefügt werden, zu komprimieren. Jedes Dateiattribut, das für ein Verzeichnis festgelegt werden kann und auch für neue Dateien, die zu diesem Verzeichnis hinzugefügt werden, festgelegt wird, wird als vererbtes Attribut bezeichnet.

Die Funktion CreateFile bietet einen Parameter zum Festlegen bestimmter Dateiattribute, wenn eine Datei erstellt wird. Allgemein sind diese Attribute die gängigsten, die eine Anwendung zum Zeitpunkt der Dateierstellung verwenden kann, aber nicht alle möglichen Dateiattribute sind für CreateFile verfügbar. Einige Dateiattribute erfordern die Verwendung anderer Funktionen, wie SetFileAttributes, DeviceIoControl oder DecryptFile, nachdem die Datei bereits existiert. Im Fall von FILE_ATTRIBUTE_DIRECTORY ist die Funktion CreateDirectory zum Zeitpunkt der Erstellung erforderlich, da CreateFile keine Verzeichnisse erstellen kann. Die anderen Dateiattribute, die eine besondere Behandlung erfordern, sind FILE_ATTRIBUTE_REPARSE_POINT und FILE_ATTRIBUTE_SPARSE_FILE, die DeviceIoControl erfordern. Weitere Informationen finden Sie unter SetFileAttributes.

Wie bereits erwähnt, erfolgt die Vererbung von Dateiattributen, wenn eine Datei mit Dateiattributen erstellt wird, die aus den Verzeichnisattributen gelesen werden, in denen sich die Datei befinden wird. Die folgende Tabelle fasst diese vererbten Attribute und ihre Beziehung zu den CreateFile-Funktionalitäten zusammen.

Status der Verzeichnisattribute CreateFile-Vererbungs-Überschreibungsfunktionalitäten für neue Dateien
FILE_ATTRIBUTE_COMPRESSED festgelegt.
Keine Steuerung. Verwenden Sie DeviceIoControl zum Löschen.
FILE_ATTRIBUTE_COMPRESSED nicht festgelegt.
Keine Steuerung. Verwenden Sie DeviceIoControl zum Festlegen.
FILE_ATTRIBUTE_ENCRYPTED festgelegt.
Keine Steuerung. Verwenden Sie DecryptFile.
FILE_ATTRIBUTE_ENCRYPTED nicht festgelegt.
Kann mit CreateFile festgelegt werden.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED festgelegt.
Keine Steuerung. Verwenden Sie SetFileAttributes zum Löschen.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED nicht festgelegt.
Keine Steuerung. Verwenden Sie SetFileAttributes zum Festlegen.

Zugriffssteuerung

CreateFile

DeviceIoControl

Dateiattributskonstanten

Dateikomprimierung und -dekomprimierung

Dateiverschlüsselung

Funktionen zur Dateiverwaltung

Handles und Objekte

Handle-Vererbung

Öffnen einer Datei zum Lesen oder Schreiben

SetFileAttributes