Membuat dan Membuka File
Fungsi CreateFile dapat membuat file baru atau membuka file yang sudah ada. Anda harus menentukan nama file, instruksi pembuatan, dan atribut lainnya. Saat aplikasi membuat file baru, sistem operasi menambahkannya ke direktori yang ditentukan.
Sistem operasi menetapkan pengidentifikasi unik, yang disebut handel, ke setiap file yang dibuka atau dibuat menggunakan CreateFile. Aplikasi dapat menggunakan handel ini dengan fungsi yang membaca dari, menulis ke, dan menjelaskan file. Ini berlaku sampai semua referensi ke handel tersebut ditutup. Ketika aplikasi dimulai, aplikasi mewarisi semua handel terbuka dari proses yang memulainya jika handel dibuat sebagai dapat diwariskan.
Aplikasi harus memeriksa nilai handel yang dikembalikan oleh CreateFile sebelum mencoba menggunakan handel untuk mengakses file. Jika terjadi kesalahan, nilai handel akan INVALID_HANDLE_VALUE dan aplikasi dapat menggunakan fungsi GetLastError untuk informasi kesalahan yang diperluas.
Ketika aplikasi menggunakan CreateFile, aplikasi harus menggunakan parameter dwDesiredAccess untuk menentukan apakah aplikasi ingin membaca dari file, menulis ke file, baik membaca dan menulis, atau tidak. Ini dikenal sebagai meminta mode akses. Aplikasi juga harus menggunakan parameter dwCreationDisposition untuk menentukan tindakan apa yang harus diambil jika file sudah ada, yang dikenal sebagai disposisi pembuatan. Misalnya, aplikasi dapat memanggil CreateFile dengan dwCreationDisposition diatur ke CREATE_ALWAYS untuk selalu membuat file baru, bahkan jika file dengan nama yang sama sudah ada (sehingga menimpa file yang ada). Apakah ini berhasil atau tidak tergantung pada faktor-faktor seperti atribut file sebelumnya dan pengaturan keamanan (lihat bagian berikut untuk informasi selengkapnya).
Aplikasi juga menggunakan CreateFile untuk menentukan apakah aplikasi ingin berbagi file untuk membaca, menulis, keduanya, atau tidak. Ini dikenal sebagai mode berbagi. File terbuka yang tidak dibagikan (dwShareMode diatur ke nol) tidak dapat dibuka lagi, baik oleh aplikasi yang membukanya atau oleh aplikasi lain, sampai handelnya ditutup. Ini juga disebut sebagai akses eksklusif.
Ketika proses menggunakan CreateFile untuk mencoba membuka file yang telah dibuka dalam mode berbagi (dwShareMode diatur ke nilai nonzero yang valid), sistem membandingkan mode akses dan berbagi yang diminta dengan yang ditentukan ketika file dibuka. Jika Anda menentukan mode akses atau berbagi yang bertentangan dengan mode yang ditentukan dalam panggilan sebelumnya, CreateFile gagal.
Tabel berikut mengilustrasikan kombinasi valid dari dua panggilan ke CreateFile menggunakan berbagai mode akses dan mode berbagi (dwDesiredAccess, dwShareMode masing-masing). Tidak masalah di mana panggilan CreateFile dilakukan. Namun, setiap operasi I/O file berikutnya pada setiap handel file masih akan dibatasi oleh mode akses dan berbagi saat ini yang terkait dengan handel file tertentu.
Panggilan pertama ke CreateFile | Panggilan kedua yang valid ke CreateFile |
---|---|
GENERIC_READ, FILE_SHARE_READ |
|
GENERIC_READ, FILE_SHARE_WRITE |
|
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE
|
GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_WRITE, FILE_SHARE_WRITE |
|
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE |
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE |
|
Selain atribut file standar, Anda juga dapat menentukan atribut keamanan dengan menyertakan penunjuk ke struktur SECURITY_ATTRIBUTES sebagai parameter keempat CreateFile. Namun, sistem file yang mendasar harus mendukung keamanan agar ini memiliki efek apa pun (misalnya, sistem file NTFS mendukungnya tetapi berbagai sistem file FAT tidak). Untuk informasi selengkapnya tentang atribut keamanan, lihat Kontrol Akses.
Aplikasi yang membuat file baru dapat menyediakan handel opsional ke file templat, tempat CreateFile mengambil atribut file dan atribut yang diperluas untuk pembuatan file baru.
Skenario CreateFile
Ada beberapa skenario mendasar untuk memulai akses ke file menggunakan fungsi CreateFile. Ini dirangkum sebagai:
- Membuat file baru ketika file dengan nama tersebut belum ada.
- Membuat file baru meskipun file dengan nama yang sama sudah ada, menghapus datanya dan mulai kosong.
- Membuka file yang ada hanya jika ada, dan hanya utuh.
- Membuka file yang ada hanya jika ada, memotongnya menjadi kosong.
- Membuka file selalu: apa adanya jika ada, buat file baru jika tidak ada.
Skenario ini dikontrol oleh penggunaan parameter dwCreationDisposition yang tepat. Di bawah ini adalah perincian tentang bagaimana skenario ini memetakan ke nilai untuk parameter ini dan apa yang terjadi ketika digunakan.
Saat membuat atau membuka file baru saat file dengan nama tersebut belum ada (dwCreationDisposition diatur ke CREATE_NEW, CREATE_ALWAYS, atau OPEN_ALWAYS), fungsi CreateFile melakukan tindakan berikut:
- Menggabungkan atribut file dan bendera yang ditentukan oleh dwFlagsAndAttributes dengan FILE_ATTRIBUTE_ARCHIVE.
- Mengatur panjang file ke nol.
- Menyalin atribut yang diperluas yang disediakan oleh file templat ke file baru jika parameter hTemplateFile ditentukan (ini mengambil alih semua bendera FILE_ATTRIBUTE_* yang ditentukan sebelumnya).
- Mengatur bendera warisan yang ditentukan oleh anggota bInheritHandle dan deskriptor keamanan yang ditentukan oleh anggota lpSecurityDescriptor dari parameter lpSecurityAttributes (struktur SECURITY_ATTRIBUTES ), jika disediakan.
Saat membuat file baru meskipun file dengan nama yang sama sudah ada (dwCreationDisposition diatur ke CREATE_ALWAYS), fungsi CreateFile melakukan tindakan berikut:
- Memeriksa atribut file saat ini dan pengaturan keamanan untuk akses tulis, gagal jika ditolak.
- Menggabungkan atribut file dan bendera yang ditentukan oleh dwFlagsAndAttributes dengan FILE_ATTRIBUTE_ARCHIVE dan atribut file yang ada.
- Mengatur panjang file ke nol (yaitu, data apa pun yang ada dalam file tidak lagi tersedia dan file kosong).
- Menyalin atribut yang diperluas yang disediakan oleh file templat ke file baru jika parameter hTemplateFile ditentukan (ini mengambil alih semua bendera FILE_ATTRIBUTE_* yang ditentukan sebelumnya).
- Mengatur bendera warisan yang ditentukan oleh anggota bInheritHandle dari parameter lpSecurityAttributes (struktur SECURITY_ATTRIBUTES) jika disediakan, tetapi mengabaikan anggota lpSecurityDescriptor dari struktur SECURITY_ATTRIBUTES.
- Jika berhasil (yaitu, CreateFile mengembalikan handel yang valid), memanggil GetLastError akan menghasilkan kode ERROR_ALREADY_EXISTS, meskipun untuk kasus penggunaan khusus ini sebenarnya bukan kesalahan seperti itu (jika Anda bermaksud membuat file "baru" (kosong) menggantikan yang sudah ada).
Saat membuka file yang ada (dwCreationDisposition diatur ke OPEN_EXISTING, OPEN_ALWAYS, atau TRUNCATE_EXISTING), fungsi CreateFile melakukan tindakan berikut:
- Memeriksa atribut file saat ini dan pengaturan keamanan untuk akses yang diminta, gagal jika ditolak.
- Menggabungkan bendera file (FILE_FLAG_*) yang ditentukan oleh dwFlagsAndAttributes dengan atribut file yang ada, dan mengabaikan atribut file apa pun (FILE_ATTRIBUTE_*) yang ditentukan oleh dwFlagsAndAttributes.
- Mengatur panjang file ke nol hanya jika dwCreationDisposition diatur ke TRUNCATE_EXISTING, jika tidak, panjang file saat ini dipertahankan dan file dibuka apa adanya.
- Mengabaikan parameter hTemplateFile.
- Mengatur bendera warisan yang ditentukan oleh anggota bInheritHandle dari parameter lpSecurityAttributes (struktur SECURITY_ATTRIBUTES) jika disediakan, tetapi mengabaikan anggota lpSecurityDescriptor dari struktur SECURITY_ATTRIBUTES.
Atribut dan Direktori File
Atribut file adalah bagian dari metadata yang terkait dengan file atau direktori, masing-masing dengan tujuan dan aturannya sendiri tentang bagaimana ia dapat diatur dan diubah. Beberapa atribut ini hanya berlaku untuk file, dan beberapa hanya untuk direktori. Misalnya, atribut FILE_ATTRIBUTE_DIRECTORY hanya berlaku untuk direktori: Ini digunakan oleh sistem file untuk menentukan apakah objek pada disk adalah direktori, tetapi tidak dapat diubah untuk objek sistem file yang ada.
Beberapa atribut file dapat diatur untuk direktori tetapi hanya memiliki arti untuk file yang dibuat di direktori tersebut, bertindak sebagai atribut default. Misalnya, FILE_ATTRIBUTE_COMPRESSED dapat diatur pada objek direktori, tetapi karena objek direktori itu sendiri tidak berisi data aktual, itu tidak benar-benar dikompresi; namun, direktori yang ditandai dengan atribut ini memberi tahu sistem file untuk mengompres file baru apa pun yang ditambahkan ke direktori tersebut. Atribut file apa pun yang dapat diatur pada direktori dan juga akan diatur untuk file baru yang ditambahkan ke direktori tersebut disebut sebagai atribut yang diwariskan.
Fungsi CreateFile menyediakan parameter untuk mengatur atribut file tertentu saat file dibuat. Secara umum, atribut ini adalah yang paling umum untuk digunakan aplikasi pada waktu pembuatan file, tetapi tidak semua atribut file yang mungkin tersedia untuk CreateFile. Beberapa atribut file memerlukan penggunaan fungsi lain, seperti SetFileAttributes, DeviceIoControl, atau DecryptFile setelah file sudah ada. Dalam kasus FILE_ATTRIBUTE_DIRECTORY, fungsi CreateDirectory diperlukan pada waktu pembuatan karena CreateFile tidak dapat membuat direktori. Atribut file lain yang memerlukan penanganan khusus adalah FILE_ATTRIBUTE_REPARSE_POINT dan FILE_ATTRIBUTE_SPARSE_FILE, yang memerlukan DeviceIoControl. Untuk informasi selengkapnya, lihat SetFileAttributes.
Seperti yang dinyatakan sebelumnya, pewarisan atribut file terjadi ketika file dibuat dengan atribut file yang dibaca dari atribut direktori tempat file akan berada. Tabel berikut ini meringkas atribut yang diwariskan ini dan hubungannya dengan kemampuan CreateFile.
Status atribut direktori | Kemampuan penggantian pewarisan CreateFile untuk file baru |
---|---|
FILE_ATTRIBUTE_COMPRESSED diatur. |
Tidak ada kontrol. Gunakan DeviceIoControl untuk menghapus. |
FILE_ATTRIBUTE_COMPRESSED tidak diatur. |
Tidak ada kontrol. Gunakan DeviceIoControl untuk mengatur. |
FILE_ATTRIBUTE_ENCRYPTED diatur. |
Tidak ada kontrol. Gunakan DecryptFile. |
FILE_ATTRIBUTE_ENCRYPTED tidak diatur. |
Dapat diatur menggunakan CreateFile. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED diatur. |
Tidak ada kontrol. Gunakan SetFileAttributes untuk menghapus. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED tidak diatur. |
Tidak ada kontrol. Gunakan SetFileAttributes untuk mengatur. |