Input dan Output Berkas

Membaca dan menulis berkas dengan My.Computer.FileSystem serta StreamReader/Writer.

Daftar isi

Data yang disimpan hanya dalam variabel hilang ketika program berhenti, sehingga program yang sungguh digunakan membutuhkan tempat penyimpanan yang bertahan. Topik ini membahas membaca dan menulis berkas teks di Visual Basic dengan dua pendekatan, yaitu metode bersama kelas Microsoft.VisualBasic.FileIO.FileSystem dan pustaka System.IO yang bekerja melalui stream, yakni objek yang menyalin data secara bertahap. Setelah topik ini dibaca, berkas contoh dapat dibuat, ditambah isinya, dibaca, diperiksa keberadaannya, dan dihapus dengan pola yang aman.

Metode bersama kelas FileSystem#

Kelas Microsoft.VisualBasic.FileIO.FileSystem menyiapkan metode bersama (Shared) yang mengoperasikan satu berkas utuh dalam satu pemanggilan. Empat metode yang paling sering digunakan adalah WriteAllText untuk menulis, ReadAllText untuk membaca seluruh isi, FileExists untuk memeriksa keberadaan, dan DeleteFile untuk menghapus. Karena seluruhnya metode bersama, pemanggilan dilakukan langsung pada nama kelas tanpa membuat objek terlebih dahulu. Penamaan berkas tanpa jalur lengkap diarahkan ke folder kerja program, yaitu folder tempat perintah dotnet run dijalankan.

Program berikut membuat berkas catatan.txt, menambah satu baris, membaca isinya, lalu menghapusnya kembali. Jalankan dengan dotnet run, lalu cocokkan keluarannya dengan urutan pemanggilan pada kode.

vb ArsipCatatan.vb
Option Strict On

Imports Microsoft.VisualBasic.FileIO

Module Program

    Sub Main()
        Dim jalur As String = "catatan.txt"

        ' Menulis berkas baru dengan parameter append bernilai False
        FileSystem.WriteAllText(jalur, "Catatan pertama" & vbCrLf, False)

        ' Menambah satu baris tanpa menimpa isi yang sudah ada
        FileSystem.WriteAllText(jalur, "Catatan kedua" & vbCrLf, True)

        ' Memeriksa keberadaan berkas sebelum membaca
        If FileSystem.FileExists(jalur) Then
            Dim isi As String = FileSystem.ReadAllText(jalur)
            Console.Write(isi)
        End If

        ' Menghapus berkas contoh agar eksekusi ulang tetap idempoten
        FileSystem.DeleteFile(jalur)
        Console.WriteLine("Ada setelah dihapus: " & FileSystem.FileExists(jalur))
    End Sub
End Module
text Keluaran
Catatan pertama
Catatan kedua
Ada setelah dihapus: False

Parameter ketiga WriteAllText menentukan perilaku penulisannya. Nilai False menimpa isi berkas yang sudah ada, sedangkan nilai True menambah teks baru di belakang isi lama, sehingga dua pemanggilan berturut-turut menghasilkan dua baris. Pemeriksaan FileExists mencegah error FileNotFoundException apabila berkas sedang tidak ada. Pemanggilan DeleteFile di akhir hanya mengosongkan folder contoh, dan keluarannya berakhir False karena berkas memang sudah tidak ada.

Stream klasik dengan StreamReader dan StreamWriter#

Metode utuh berkas nyaman untuk berkas teks kecil, tetapi memuat seluruh isi ke memori tidak tepat untuk berkas besar. Kelas StreamWriter dan StreamReader pada System.IO menangani situasi itu dengan membuka berkas sebagai stream, lalu menulis atau membaca satu baris pada satu waktu. Metode WriteLine milik StreamWriter menambahkan teks beserta penanda akhir baris, sedangkan ReadLine milik StreamReader mengembalikan satu baris tanpa penandanya, serta Nothing ketika berkas habis. Keduanya merupakan resource yang wajib ditutup, dan blok Using dari topik disposisi menjamin penutupan itu terjadi meskipun exception terjadi.

Konstruktor StreamWriter dengan satu argumen membuat berkas bila belum ada dan menimpa isinya bila sudah ada, sedangkan bentuk kedua yang membawa argumen True membukanya untuk penambahan. ReadLine memotong penanda akhir baris dari hasil bacaannya, sehingga teks yang diperoleh tidak perlu dibersihkan lagi. WriteLine menuliskan penanda itu kembali pada setiap barisnya, sehingga berkas hasilnya dapat dibaca ulang dengan pola yang sama.

Program berikut menulis tiga nilai ujian dengan StreamWriter, lalu menghitung ulang isinya dengan StreamReader.

vb BacaTulisStream.vb
Option Strict On

Imports System.IO

Module Program

    Sub Main()
        ' Menulis baris demi baris dengan StreamWriter di dalam blok Using
        Using penulis As New StreamWriter("nilai-ujian.txt")
            penulis.WriteLine("80")
            penulis.WriteLine("95")
            penulis.WriteLine("72")
        End Using

        ' Membaca baris demi baris sampai ReadLine mengembalikan Nothing
        Dim total As Integer = 0
        Dim banyak As Integer = 0
        Using pembaca As New StreamReader("nilai-ujian.txt")
            Dim baris As String = pembaca.ReadLine()
            Do While baris IsNot Nothing
                total += Integer.Parse(baris)
                banyak += 1
                baris = pembaca.ReadLine()
            Loop
        End Using

        Console.WriteLine($"Banyak nilai: {banyak}")
        Console.WriteLine($"Total nilai: {total}")
        Console.WriteLine($"Rata-rata: {(total / banyak):F2}")
    End Sub
End Module
text Keluaran
Banyak nilai: 3
Total nilai: 247
Rata-rata: 82.33

Perulangan Do While berhenti ketika ReadLine mengembalikan Nothing, yaitu tepat setelah baris ketiga dibaca. Hasil hitungnya 247 dari tiga nilai, dan pemformat F2 menampilkannya sebagai rata-rata dengan dua angka desimal. Keluaran menggunakan tanda titik sebagai pemisah desimal karena format bilangan bawaan runtime mengikuti gaya Inggris.

Memilih antara metode utuh berkas dan stream#

Kedua pendekatan saling menggantikan untuk berkas teks biasa, sehingga pilihannya ditentukan oleh ukuran berkas dan pola penggunaannya. Tabel berikut merangkum perbedaan yang berpengaruh pada keputusan tersebut.

AspekMetode kelas FileSystemStreamReader dan StreamWriter
Cakupansatu berkas utuh dalam satu pemanggilanbertahap, baris demi baris
Penggunaan memoriseluruh isi dimuat sekaligussatu baris pada satu waktu
Cocok untukberkas pengaturan dan arsip kecillog, berkas besar, dan pemrosesan berurutan
Penutupan resourceselesai dalam satu pemanggilanwajib ditutup, paling mudah dengan Using

Kedua pendekatan menangani teks dengan pengodean UTF-8 secara bawaan, dan keduanya menyediakan overloading yang menerima pengodean lain apabila berkas yang dibaca ditulis dengan format lama. Kelas System.IO.File juga menyiapkan metode serupa dengan kelas FileSystem, seperti File.WriteAllText dan File.ReadAllText, sehingga kode yang tidak menyentuh bagian VB runtime tetap memiliki pilihan yang sama. Namanya berbeda tetapi perilakunya setara untuk kasus-kasus dasar, sehingga konsistensi salah satu gaya di dalam satu proyek sudah memadai.

Kesalahan umum#

Kesalahan pertama adalah menyalin contoh lama yang menggunakan My.Computer.FileSystem. Penulisan itu gagal dikompilasi pada .NET 10 dengan error BC30456 karena objek My.Computer tidak lagi disediakan. Perbaikannya sederhana, yaitu mengganti pemanggilan menjadi metode bersama kelas Microsoft.VisualBasic.FileIO.FileSystem atau pindah ke kelas-kelas System.IO, karena perilaku keduanya setara untuk operasi dasar.

Kesalahan kedua adalah menulis stream tanpa blok Using. StreamWriter menyimpan teks di penyangga (buffer) terlebih dahulu, sehingga stream yang tidak ditutup dapat meninggalkan berkas yang berhenti di tengah baris dan kehilangan bagian akhirnya. Gejalanya sering terlambat, misalnya baris terakhir yang baru hilang ketika program ditutup segera setelah menulis.

Kesalahan ketiga adalah membaca berkas tanpa memeriksa keberadaannya. Pembacaan atas berkas yang tidak ada memunculkan FileNotFoundException, sehingga gabungkan pemeriksaan FileExists untuk kasus yang ketiadaannya wajar dengan penanganan exception untuk kegagalan yang benar-benar tak terduga. Apabila berkas yang sama dibaca berulang kali, pemeriksaan satu kali tetap lebih murah daripada menangkap exception yang berulang.

Ringkasan#

  • Kelas Microsoft.VisualBasic.FileIO.FileSystem menyiapkan metode bersama WriteAllText, ReadAllText, FileExists, dan DeleteFile untuk mengoperasikan satu berkas utuh, dengan parameter append untuk menimpa atau menambah isi.
  • Objek My.Computer.FileSystem yang muncul pada contoh .NET Framework tidak tersedia pada .NET 10, sehingga bentuk kelasnya yang digunakan.
  • StreamWriter dan StreamReader menulis serta membaca baris demi baris melalui stream, ReadLine mengembalikan Nothing pada akhir berkas, dan blok Using menjamin keduanya tertutup.

Referensi#