Mari kita membuat daftar Go-kompatibel semua cara untuk membaca dan menulis file di Go.
Karena file API telah berubah baru-baru ini dan sebagian besar jawaban lainnya tidak berfungsi dengan Go 1. Mereka juga ketinggalan bufio
IMHO yang penting.
Dalam contoh berikut ini saya menyalin file dengan membaca darinya dan menulis ke file tujuan.
Mulailah dengan dasar-dasarnya
package main
import (
"io"
"os"
)
func main() {
// open input file
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
// close fi on exit and check for its returned error
defer func() {
if err := fi.Close(); err != nil {
panic(err)
}
}()
// open output file
fo, err := os.Create("output.txt")
if err != nil {
panic(err)
}
// close fo on exit and check for its returned error
defer func() {
if err := fo.Close(); err != nil {
panic(err)
}
}()
// make a buffer to keep chunks that are read
buf := make([]byte, 1024)
for {
// read a chunk
n, err := fi.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
// write a chunk
if _, err := fo.Write(buf[:n]); err != nil {
panic(err)
}
}
}
Di sini saya menggunakan os.Open
dan os.Create
pembungkus yang nyaman di sekitar os.OpenFile
. Kami biasanya tidak perlu menelepon OpenFile
langsung.
Perhatikan merawat EOF. Read
mencoba untuk mengisi buf
setiap panggilan, dan kembali io.EOF
sebagai kesalahan jika mencapai akhir file dalam melakukannya. Dalam hal ini buf
masih akan menyimpan data. Panggilan konsekuen untuk Read
mengembalikan nol ketika jumlah byte dibaca dan sama io.EOF
dengan kesalahan. Kesalahan lainnya akan menyebabkan kepanikan.
Menggunakan bufio
package main
import (
"bufio"
"io"
"os"
)
func main() {
// open input file
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
// close fi on exit and check for its returned error
defer func() {
if err := fi.Close(); err != nil {
panic(err)
}
}()
// make a read buffer
r := bufio.NewReader(fi)
// open output file
fo, err := os.Create("output.txt")
if err != nil {
panic(err)
}
// close fo on exit and check for its returned error
defer func() {
if err := fo.Close(); err != nil {
panic(err)
}
}()
// make a write buffer
w := bufio.NewWriter(fo)
// make a buffer to keep chunks that are read
buf := make([]byte, 1024)
for {
// read a chunk
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
// write a chunk
if _, err := w.Write(buf[:n]); err != nil {
panic(err)
}
}
if err = w.Flush(); err != nil {
panic(err)
}
}
bufio
hanya bertindak sebagai penyangga di sini, karena kami tidak memiliki banyak hubungannya dengan data. Dalam kebanyakan situasi lain (khususnya dengan file teks) bufio
sangat berguna dengan memberi kami API yang bagus untuk membaca dan menulis dengan mudah dan fleksibel, sementara itu menangani buffering di belakang layar.
Menggunakan ioutil
package main
import (
"io/ioutil"
)
func main() {
// read the whole file at once
b, err := ioutil.ReadFile("input.txt")
if err != nil {
panic(err)
}
// write the whole body at once
err = ioutil.WriteFile("output.txt", b, 0644)
if err != nil {
panic(err)
}
}
Mudah seperti pai! Tetapi gunakan hanya jika Anda yakin tidak berurusan dengan file besar.
panic("error in writing")
) tidak perlu.Ini versi bagus:
sumber
0x777
palsu. Bagaimanapun, itu harus lebih seperti0644
atau0755
(oktal, bukan hex).Menggunakan
io.Copy
Jika Anda merasa tidak ingin menciptakan kembali roda, itu
io.Copy
danio.CopyN
mungkin bisa membantu Anda dengan baik. Jika Anda memeriksa sumber fungsi io.Copy, itu tidak lain adalah salah satu solusi Mostafa (yang 'dasar', sebenarnya) yang dikemas dalam Go library. Mereka menggunakan buffer yang jauh lebih besar daripada dia.sumber
w.Sync()
setelahio.Copy(w, r)
io.Copy()
hanya akan menulis data yang Anda masukkan, jadi jika file yang ada memiliki lebih banyak konten, itu tidak akan dihapus, yang dapat mengakibatkan file rusak.w, err := os.Create("output.txt")
, apa yang Anda jelaskan tidak terjadi, karena "Buat membuat atau memotong file bernama. Jika file sudah ada, itu terpotong." golang.org/pkg/os/#Create .Dengan versi Go yang lebih baru, membaca / menulis ke / dari file itu mudah. Untuk membaca dari file:
Untuk menulis ke file:
Ini akan menimpa konten file (buat file baru jika tidak ada).
sumber
[]byte
adalah slice (mirip dengan substring) dari semua atau bagian dari array byte. Pikirkan slice sebagai struktur nilai dengan bidang penunjuk tersembunyi untuk sistem untuk menemukan dan mengakses semua atau bagian dari array (slice), ditambah bidang untuk panjang dan kapasitas slice, yang dapat Anda akses menggunakanlen()
dancap()
fungsi .Ini kit starter yang berfungsi untuk Anda, yang membaca dan mencetak file biner; Anda perlu mengubah nilai
inName
literal untuk merujuk ke file kecil di sistem Anda.sumber
if
blokCoba ini:
sumber
Hanya dengan melihat dokumentasi sepertinya Anda harus mendeklarasikan buffer bertipe [] byte dan meneruskannya untuk membaca yang kemudian akan membaca hingga banyak karakter dan mengembalikan jumlah karakter yang benar-benar dibaca (dan kesalahan).
Dokumen mengatakan
Apakah itu tidak berhasil?
EDIT: Juga, saya pikir Anda mungkin harus menggunakan antarmuka Reader / Writer yang dinyatakan dalam paket bufio daripada menggunakan paket os .
sumber
Metode Read mengambil parameter byte karena itu buffer yang akan dibaca. Ini adalah Idiom yang umum di beberapa kalangan dan masuk akal ketika Anda memikirkannya.
Dengan cara ini Anda dapat menentukan berapa banyak byte yang akan dibaca oleh pembaca dan memeriksa kembali untuk melihat berapa banyak byte yang benar-benar dibaca dan menangani kesalahan dengan tepat.
Seperti yang orang lain tunjukkan dalam jawaban mereka, bufio mungkin adalah apa yang Anda inginkan untuk membaca dari sebagian besar file.
Saya akan menambahkan satu petunjuk lain karena ini sangat berguna. Membaca satu baris dari suatu file paling baik dilakukan bukan dengan metode ReadLine tetapi metode ReadBytes atau ReadString.
sumber