File dan Path

Operasi File, Directory, dan Path.

Daftar isi

Topik ini membahas operasi berkas pada C# menggunakan tiga kelas dari namespace System.IO, yaitu File untuk berkas tunggal, Directory untuk folder, dan Path untuk membangun serta mengurai jalur berkas. Pembahasan mencakup membuat, membaca, menambah, memeriksa, dan menghapus berkas, kemudian menelusuri isi folder, dan diakhiri penyusunan jalur yang benar di berbagai sistem operasi. Seluruh contoh dijalankan langsung dan keluarannya ditampilkan apa adanya.

Operasi berkas dengan kelas File#

Kelas File menyediakan metode statis untuk operasi berkas tanpa perlu membuat objek terlebih dahulu. Metode WriteAllText menulis satu teks ke berkas dengan membuatnya apabila belum ada dan menimpa isinya apabila sudah ada, sedangkan AppendAllText menambahkan teks di bagian akhir tanpa menghapus isi sebelumnya. Pembacaan dilakukan dengan ReadAllText yang mengembalikan seluruh isi berkas sebagai satu string, dan keberadaan berkas diperiksa dengan Exists yang mengembalikan nilai bool. Contoh berikut merangkai operasi tersebut pada satu berkas catatan yang disimpan di dalam folder arsip.

csharp Program.cs
// Program: operasi dasar berkas dengan kelas File dan Directory
string folder = "arsip";
string jalur = Path.Combine(folder, "catatan.txt");

Directory.CreateDirectory(folder);
File.WriteAllText(jalur, "Baris pertama dari catatan.");
Console.WriteLine($"Berkas ada: {File.Exists(jalur)}");

File.AppendAllText(jalur, "\nBaris kedua ditambahkan.");
Console.WriteLine("--- isi catatan.txt ---");
Console.WriteLine(File.ReadAllText(jalur));
Console.WriteLine($"Ukuran: {new FileInfo(jalur).Length} byte");

File.Delete(jalur);
Directory.Delete(folder);
Console.WriteLine($"Folder ada setelah dihapus: {Directory.Exists(folder)}");
text Keluaran
Berkas ada: True
--- isi catatan.txt ---
Baris pertama dari catatan.
Baris kedua ditambahkan.
Ukuran: 52 byte
Folder ada setelah dihapus: False

Untuk menjalankan program tersebut dari folder topik, gunakan perintah berikut.

bash
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# jalankan program contoh dari folder topik
dotnet run --file Program.cs
text Keluaran
Berkas ada: True
--- isi catatan.txt ---
Baris pertama dari catatan.
Baris kedua ditambahkan.
Ukuran: 52 byte
Folder ada setelah dihapus: False

Keluaran mengikuti urutan penulisannya satu per satu. Pemanggilan WriteAllText membuat folder arsip beserta berkas catatan.txt sekaligus, sehingga pemeriksaan Exists mengembalikan True. Pemanggilan AppendAllText menambahkan baris kedua, dan ReadAllText mengembalikan kedua baris itu utuh. Ukuran berkas dibaca dari property Length milik kelas FileInfo yang menghitung jumlah byte pada disk, yaitu 27 byte untuk baris pertama, 24 byte untuk baris kedua, ditambah satu byte penanda baris. Dua metode penghapusan di bagian akhir membersihkan berkas dan foldernya, sehingga pemeriksaan terakhir mengembalikan False.

Perlu dicatat bahwa File tidak menyediakan pembacaan ukuran, sehingga contoh memakai kelas FileInfo yang membungkus satu jalur berkas. FileInfo menyajikan ukuran, tanggal perubahan, dan atribut berkas melalui property-nya, sedangkan File menangani operasi yang berdiri sendiri. Keduanya saling melengkapi, dan pemilihannya mengikuti bentuk kebutuhan, yaitu satu operasi tunggal untuk File atau beberapa pembacaan atas berkas yang sama untuk FileInfo.

Menelusuri folder dengan kelas Directory#

Kelas Directory mengelola folder secara keseluruhan, dari pembuatan, penelusuran, hingga penghapusan. Metode CreateDirectory membuat folder yang diminta lengkap dengan seluruh induknya sekaligus, sehingga pemanggilan satu kali sudah cukup untuk menyusun folder bertingkat. Metode GetFiles mengembalikan larik nama berkas di dalam satu folder dan menerima pola pencarian seperti *.csv untuk memilah berkas menurut ekstensinya. Contoh berikut membuat folder data, mengisinya dengan tiga berkas, kemudian menampilkan hanya berkas berekstensi csv.

csharp Contoh: menelusuri isi folder data
// Contoh: menelusuri isi folder data
Directory.CreateDirectory("data");
File.WriteAllText(Path.Combine("data", "sensor-1.csv"), "suhu,kelembapan");
File.WriteAllText(Path.Combine("data", "sensor-2.csv"), "suhu,kelembapan");
File.WriteAllText(Path.Combine("data", "bacaan.txt"), "teks pendek");

foreach (string berkas in Directory.GetFiles("data", "*.csv"))
{
    Console.WriteLine(berkas);
}

Directory.Delete("data", recursive: true);
Console.WriteLine($"Folder ada: {Directory.Exists("data")}");
text Keluaran
data/sensor-1.csv
data/sensor-2.csv
Folder ada: False

Pola *.csv menyaring bacaan.txt sehingga hanya dua berkas sensor yang tampil. Untuk folder berisi ratusan berkas, metode EnumerateFiles lebih tepat daripada GetFiles karena mengembalikan nama satu per satu melalui IEnumerable<string> saat penelusuran berjalan, sedangkan GetFiles menunggu seluruh daftar terkumpul lebih dahulu. Pemilihan keduanya tidak mengubah hasil, melainkan mengubah kapan hasil pertama tersedia. Pemanggilan GetFiles dengan argumen ketiga SearchOption.AllDirectories menelusuri subfolder secara berulang, sedangkan tanpa argumen itu penelusuran berhenti di folder yang diminta. Penghapusan folder data memerlukan argumen recursive: true karena foldernya masih berisi berkas, dan tanpa argumen tersebut metode Delete menolak menghapus folder yang tidak kosong.

Membangun dan mengurai jalur dengan kelas Path#

Kelas Path menyusun dan membongkar teks jalur tanpa menyentuh berkas apa pun. Metode Combine menggabungkan beberapa segmen menjadi satu jalur dengan pemisah yang sesuai sistem operasi, sedangkan metode GetFileName, GetFileNameWithoutExtension, dan GetExtension mengambil bagian tertentu dari sebuah jalur. Metode ChangeExtension mengganti ekstensi terakhir dengan yang baru tanpa menyentuh berkas aslinya. Contoh berikut memperlihatkan kelimanya pada satu jalur contoh.

csharp Contoh: membangun dan mengurai jalur
// Contoh: membangun dan mengurai jalur
string jalur = Path.Combine("data", "bacaan", "laporan.txt");
Console.WriteLine(jalur);
Console.WriteLine(Path.GetFileName(jalur));
Console.WriteLine(Path.GetFileNameWithoutExtension(jalur));
Console.WriteLine(Path.GetExtension(jalur));
Console.WriteLine(Path.ChangeExtension(jalur, ".csv"));
Console.WriteLine($"Pemisah folder: {Path.DirectorySeparatorChar}");
text Keluaran
data/bacaan/laporan.txt
laporan.txt
laporan
.txt
data/bacaan/laporan.csv
Pemisah folder: /

Jalur pada contoh-contoh di atas bersifat relatif, yaitu dihitung dari folder kerja program dan bukan dari akar sistem berkas. Folder kerja adalah folder tempat program dijalankan, sehingga jalur arsip/catatan.txt menunjuk ke tempat yang berbeda apabila program dijalankan dari folder lain. Jalur mutlak memecahkan ketidakpastian itu karena bermula dari akar, misalnya /var/log pada Linux atau C:\log pada Windows, tetapi membuat program tidak dapat dipindahkan. Kelas Path juga menyediakan GetFullPath yang mengubah jalur relatif menjadi mutlak berdasarkan folder kerja saat itu.

Property DirectorySeparatorChar mengembalikan karakter pemisah folder sistem yang menjalankan program, yaitu garis miring / pada Linux dan macOS serta garis miring terbalik \ pada Windows. Seluruh metode penguraian mengikuti pemisah tersebut, sehingga hasilnya tetap benar apabila program dipindahkan antarsistem operasi.

Kesalahan umum#

Tiga kesalahan berikut paling sering muncul ketika operasi berkas dipraktikkan pertama kali. Masing-masing menimbulkan exception saat program berjalan, sehingga penyebab dan perbaikannya perlu dikenali lebih awal.

  • Mengasumsikan berkas pasti ada. Pembacaan ReadAllText atas berkas yang belum ada melempar FileNotFoundException. Perbaikannya adalah memeriksa File.Exists terlebih dahulu atau menangkap exception tersebut ketika ketiadaan berkas memang mungkin terjadi.
  • Menghapus folder yang masih berisi tanpa argumen recursive. Pemanggilan Directory.Delete("data") atas folder berisi melempar IOException karena isinya akan hilang. Berikan recursive: true apabila penghapusan menyeluruh memang dimaksudkan.
  • Menyusun jalur dengan penyambungan string. Jalur yang disambung manual tidak memperhatikan pemisah sistem operasi dan mudah melewatkan satu pemisah. Susun seluruh jalur dengan Path.Combine.

Ringkasan#

  • File menyediakan metode statis WriteAllText, AppendAllText, ReadAllText, Exists, dan Delete untuk operasi berkas tunggal.
  • Directory membuat, menelusuri, dan menghapus folder, dengan argumen recursive untuk folder yang masih berisi.
  • Path.Combine menyusun jalur sesuai sistem operasi, sedangkan GetFileName, GetExtension, dan ChangeExtension mengurai bagian-bagiannya.

Referensi#