Hãy tạo một danh sách tương thích với Go 1 về tất cả các cách để đọc và ghi tệp trong Go.
Bởi vì API tệp đã thay đổi gần đây và hầu hết các câu trả lời khác không hoạt động với Go 1. Họ cũng bỏ lỡ bufioIMHO quan trọng.
Trong các ví dụ sau tôi sao chép một tệp bằng cách đọc từ nó và ghi vào tệp đích.
Bắt đầu với những điều cơ bản
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)
}
}
}
Ở đây tôi đã sử dụng os.Openvà os.Createđó là các trình bao bọc thuận tiện xung quanh os.OpenFile. Chúng tôi thường không cần gọi OpenFiletrực tiếp.
Thông báo điều trị EOF. Readcố gắng điền bufvào mỗi cuộc gọi và trả về io.EOFlà lỗi nếu nó đến cuối tập tin khi thực hiện. Trong trường hợp bufnày vẫn sẽ giữ dữ liệu. Các cuộc gọi tiếp theo Readtrả về 0 là số byte được đọc và giống io.EOFnhư lỗi. Bất kỳ lỗi nào khác sẽ dẫn đến hoảng loạn.
Sử dụng 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)
}
}
bufiochỉ đóng vai trò là bộ đệm ở đây, vì chúng ta không liên quan nhiều đến dữ liệu. Trong hầu hết các tình huống khác (đặc biệt với các tệp văn bản) bufiorất hữu ích bằng cách cung cấp cho chúng tôi một API đẹp để đọc và viết dễ dàng và linh hoạt, trong khi nó xử lý bộ đệm phía sau hậu trường.
Sử dụng 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)
}
}
Dễ như ăn bánh! Nhưng chỉ sử dụng nó nếu bạn chắc chắn rằng bạn không xử lý các tệp lớn.