Ana içeriğe geç
Modül 8 · Ders 3 ders 5Kurstaki 38/50~14 min
Modül dersleri (3/5)

'io' ve 'os': dosyalar ve akışlar

Go'da dosya ve akış okumak ve yazmak iki tamamlayıcı paket etrafında döner: os (açma, oluşturma, meta veriler, işlemler) ve io (herhangi bir bayt kaynağını soyutlayan Reader/Writer arayüzleri).

Dosyaları okuma ve yazma: kısayollar

Küçük dosyalar veya yapılandırma dosyaları için tek bir çağrı yeterlidir:

Go
data, err := os.ReadFile("input.txt")        // returns []byte
if err != nil {
    return err
}
fmt.Println(string(data))

err = os.WriteFile("out.txt", []byte("ciao"), 0644)

os.ReadFile açılır, her şeyi belleğe okur ve kapanır. Birkaç MB'a kadar mükemmel; bunun ötesinde akış daha iyidir.

Dosyaları akış için açma

Büyük dosyalar veya artımlı erişim için dosyayı açın ve defer ile kapatın:

Go
f, err := os.Open("big.txt")        // read-only
if err != nil {
    return err
}
defer f.Close()

buf := make([]byte, 4096)
for {
    n, err := f.Read(buf)
    if n > 0 {
        process(buf[:n])
    }
    if err == io.EOF {
        break
    }
    if err != nil {
        return err
    }
}

os.Open salt okunur olarak açılır. Yazmak için os.Create (varsa kesilir) veya os.OpenFile(path, flag, perm) komutunu os.O_APPEND | os.O_CREATE | os.O_WRONLY gibi bayraklarla kullanın.

io.Reader ve io.Writer: evrensel arayüzler

Go
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }

Standart kütüphanenin io.Reader kabul ettiği her yerde, bir dosyayı (*os.File), bir dizeyi (strings.NewReader), bir *bytes.Buffer, bir HTTP yanıtını (resp.Body), bir açıcıyı iletebilirsiniz... Aynı şey io.Writer için de geçerlidir.

Go
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)

io.Copy bayt işlem hatları için en güçlü iş makinesidir: ara belleğe almayı ve EOF'yi doğru şekilde işler. io.ReadAll(r), EOF'ye kadar olan her şeyi []byte'ye okur.

os.Args: CLI bağımsız değişkenleri

os.Args bir dizi dizedir: dizin 0 gerçek argümanlardaki 1'den program adıdır:

Go
func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "uso: prog <nome>")
        os.Exit(1)
    }
    fmt.Println("ciao", os.Args[1])
}

Daha yapılandırılmış ayrıştırma için (bayraklar, varsayılanlar, yardım), stdlib'deki flag paketini veya cobra gibi harici kitaplıkları kullanın.

os.Stdin, os.Stdout, os.Stderr

Bunlar üç genel *os.Files'dir: io.Reader veya io.Writer kabul edildiği her yerde bunları geçebilirsiniz.

Go
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin)  // echo

Egzersizler

Egzersiz#go.m8.l3.e1
Denemeler: 0Yükleniyor…

İlk komut satırı argümanını yazdırın (os.Args[1]). Eksikse 'manca argomento' yazdırın ve geri dönün.

Düzenleyici yükleniyor…

3 denemeden sonra çözüm mevcut

Egzersiz#go.m8.l3.e2
Denemeler: 0Yükleniyor…

'ciao' dizesini os.WriteFile (izinler 0644) ile 'out.txt' dosyasına yazın. Hatayı halledin.

Düzenleyici yükleniyor…

3 denemeden sonra çözüm mevcut

Quiz#go.m8.l3.e3
Hazır

os.Args'daki PROGRAM ADI'nın dizini nedir?

Go
fmt.Println(os.Args[???])
Cevap seçenekleri