1. Dasar-dasar Pustaka OS

Pustaka os dalam Golang menyediakan antarmuka yang independen dari platform untuk fungsi sistem operasi. Selanjutnya, kita akan membahas cara menggunakan pustaka os untuk menangani pembukaan, penutupan, pembacaan, penulisan file, serta mengakses dan mengatur atribut file.

1.1 Membuka dan Menutup File

Dalam bahasa Go, Anda dapat menggunakan fungsi os.Open untuk membuka file, yang akan mengembalikan objek *os.File dan sebuah error. Setelah file terbuka, Anda dapat melakukan operasi baca, tulis, dan lainnya. Setelah operasi selesai, Anda harus memanggil file.Close untuk menutup file dan membebaskan sumber daya yang sesuai.

Berikut contoh membuka file:

package main

import (
    "fmt"
    "os"
)

func main() {
    // Buka file test.txt di direktori saat ini
    file, err := os.Open("test.txt")
    if err != nil {
        // Tangani kesalahan pembukaan file
        fmt.Println("Error opening file:", err)
        return
    }
    // Gunakan pernyataan defer untuk memastikan file ditutup akhirnya
    defer file.Close()

    // Operasi penanganan file...

    fmt.Println("File berhasil dibuka")
}

Pada kode di atas, kita menggunakan pernyataan defer untuk memastikan bahwa file.Close akan dieksekusi terlepas dari kondisi. Hal ini merupakan praktik umum dalam bahasa Go untuk membersihkan sumber daya.

1.2 Operasi Baca dan Tulis File

Tipe os.File memiliki metode Read dan Write, yang dapat digunakan untuk operasi baca dan tulis file. Metode Read membaca data dari file ke dalam slice byte, dan metode Write menulis data dari slice byte ke file.

Contoh berikut mendemonstrasikan cara membaca dan menulis ke file:

package main

import (
    "fmt"
    "os"
)

func main() {
    // Buka file
    file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)
    if err != nil {
        fmt.Println("Error opening file:", err)
        return
    }
    defer file.Close()

    // Tulis konten file
    pesan := []byte("Halo, Gophers!")
    _, writeErr := file.Write(pesan)
    if writeErr != nil {
        fmt.Println("Error writing to file:", writeErr)
        return
    }

    // Baca file dari awal
    file.Seek(0, 0)
    buffer := make([]byte, len(pesan))
    _, readErr := file.Read(buffer)
    if readErr != nil {
        fmt.Println("Error reading file:", readErr)
        return
    }

    fmt.Println("Konten file:", string(buffer))
}

Pada contoh ini, kita menggunakan os.OpenFile alih-alih os.Open. Fungsi os.OpenFile memungkinkan Anda untuk menentukan mode dan izin yang akan digunakan saat membuka file. Pada contoh di atas, flag os.O_RDWR digunakan, yang berarti file akan dibuka dalam mode baca-tulis.

1.3 Properti File dan Izin

Anda dapat menggunakan fungsi dari paket os untuk mengakses dan memodifikasi informasi status file. Gunakan os.Stat atau os.Lstat untuk mendapatkan antarmuka os.FileInfo, yang menyediakan informasi tentang file, seperti ukuran, izin, waktu modifikasi, dan lainnya.

Berikut contoh bagaimana mendapatkan status file:

package main

import (
    "fmt"
    "os"
)

func main() {
    fileInfo, err := os.Stat("test.txt")
    if err != nil {
        fmt.Println("Gagal mendapatkan informasi file:", err)
        return
    }

    // Print ukuran file
    fmt.Printf("Ukuran file: %d bytes\n", fileInfo.Size())

    // Print izin file
    fmt.Printf("Izin file: %s\n", fileInfo.Mode())
}

Jika Anda perlu mengubah nama file atau memodifikasi izin file, Anda dapat menggunakan os.Rename untuk mengubah nama file atau os.Chmod untuk mengubah izin file.

package main

import (
    "fmt"
    "os"
)

func main() {
    // Mengubah izin file menjadi hanya-baca
    err := os.Chmod("test.txt", 0444)
    if err != nil {
        fmt.Println("Gagal mengubah izin file:", err)
        return
    }

    // Mengubah nama file
    renameErr := os.Rename("test.txt", "renamed.txt")
    if renameErr != nil {
        fmt.Println("Gagal mengubah nama file:", renameErr)
        return
    }
    
    fmt.Println("Operasi file sukses")
}

Di sini, kami mengubah izin file test.txt menjadi hanya-baca, lalu mengubah nama file menjadi renamed.txt. Perhatikan bahwa ketika memodifikasi izin file, berhati-hatilah, karena pengaturan izin yang salah dapat menyebabkan file tidak dapat diakses.

2. Penggunaan Dasar Pustaka IO

Dalam bahasa Go, pustaka io menyediakan antarmuka dasar untuk primitif I/O (operasi input/output). Desain pustaka io mengikuti prinsip kesederhanaan dan antarmuka seragam, menyediakan dukungan dasar untuk berbagai jenis operasi I/O, seperti membaca/menulis file, komunikasi jaringan, penyanggaan data, dan lainnya.

2.2 Menggunakan Antarmuka Pemacu dan Penulis

io.Reader dan io.Writer adalah dua antarmuka dasar yang digunakan untuk menyatakan operasi baca dan tulis dari sebuah objek. Mereka diimplementasikan oleh berbagai jenis, seperti file, koneksi jaringan, dan penyangga.

io.Reader

Antarmuka io.Reader memiliki metode Read:

Read(p []byte) (n int, err error)

Metode ini membaca hingga len(p) byte data dari io.Reader ke dalam p. Ini mengembalikan jumlah byte yang terbaca n (0 <= n <= len(p)) dan semua kesalahan yang terjadi.

Contoh kode:

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Hello, World!")

    buf := make([]byte, 4)
    for {
        n, err := r.Read(buf)
        if err == io.EOF {
            break
        }
        fmt.Printf("Byte yang terbaca: %d, Isi: %s\n", n, buf[:n])
    }
}

Pada contoh ini, kita membuat strings.NewReader untuk membaca data dari string dan kemudian membaca data dalam potongan 4 byte.

io.Writer

Antarmuka io.Writer memiliki metode Write:

Write(p []byte) (n int, err error)

Metode ini menulis data dari p ke dalam aliran data yang mendasari, mengembalikan jumlah byte yang ditulis dan semua kesalahan yang terjadi.

Contoh kode:

package main

import (
    "fmt"
    "os"
)

func main() {
    data := []byte("Hello, World!\n")
    n, err := os.Stdout.Write(data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Byte yang ditulis: %d\n", n)
}

Contoh ini menulis string sederhana ke output standar os.Stdout, yang berfungsi sebagai implementasi dari io.Writer.

2.3 Fungsi Baca/Tulis Lanjutan

Paket io menyediakan beberapa fungsi lanjutan yang dapat menyederhanakan tugas-tugas umum, seperti menyalin data dan membaca jumlah data yang ditentukan.

Fungsi Salin

io.Copy merupakan metode yang nyaman untuk langsung menyalin data dari io.Reader ke io.Writer tanpa perlu buffer perantara.

Contoh kode:

package main

import (
    "io"
    "os"
    "strings"
)

func main() {
    r := strings.NewReader("Contoh operasi menyalin sederhana")
    _, err := io.Copy(os.Stdout, r)
    if err != nil {
        panic(err)
    }
}

Pada contoh ini, kita langsung menyalin sebuah string ke output standar.

Fungsi ReadAtLeast

Fungsi io.ReadAtLeast digunakan untuk memastikan setidaknya sejumlah tertentu data dibaca dari io.Reader sebelum kembali.

func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)

Contoh kode:

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Situs web Bahasa Go")
    buf := make([]byte, 14)
    n, err := io.ReadAtLeast(r, buf, 14)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%s\n", buf[:n])
}

Pada contoh ini, io.ReadAtLeast berusaha untuk membaca setidaknya 14 byte data ke dalam buf.

Fungsi baca/tulis lanjutan ini memungkinkan Anda untuk menangani tugas-tugas terkait I/O dengan lebih efisien dan memberikan landasan kokoh untuk membangun logika program yang lebih kompleks.