Bài học theo mô-đun (3/5)
`io` và `os`: tập tin và luồng
Đọc và ghi tệp và luồng trong Go xoay quanh hai gói bổ sung: os (mở, tạo, siêu dữ liệu, quy trình) và io (giao diện Reader/Writer trừu tượng hóa mọi nguồn byte).
Đọc và ghi tập tin: các phím tắt
Đối với các tệp nhỏ hoặc cấu hình, một lệnh gọi là đủ:
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 mở, đọc mọi thứ vào bộ nhớ và đóng lại. Hoàn hảo lên tới vài MB; Ngoài ra, phát trực tuyến tốt hơn.
Mở tập tin để phát trực tuyến
Đối với các tệp lớn hoặc quyền truy cập gia tăng, hãy mở tệp và đóng tệp bằng defer:
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 mở ở chế độ chỉ đọc. Để viết, hãy sử dụng os.Create (cắt ngắn nếu nó tồn tại) hoặc os.OpenFile(path, flag, perm) với các cờ như os.O_APPEND | os.O_CREATE | os.O_WRONLY.
io.Reader và io.Writer: giao diện phổ quát
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }Bất cứ nơi nào thư viện chuẩn chấp nhận io.Reader, bạn có thể truyền một tệp (*os.File), một chuỗi (strings.NewReader), *bytes.Buffer, một phản hồi HTTP (resp.Body), một bộ giải nén... Điều tương tự cũng xảy ra với io.Writer.
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)io.Copy là đặc điểm chính của đường dẫn byte: nó xử lý việc đệm và EOF một cách chính xác. io.ReadAll(r) đọc mọi thứ cho đến khi EOF thành []byte.
os.Args: Đối số CLI
os.Args là một đoạn chuỗi: chỉ mục 0 là tên chương trình, từ 1 trên các đối số thực tế:
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "uso: prog <nome>")
os.Exit(1)
}
fmt.Println("ciao", os.Args[1])
}Để phân tích cú pháp có cấu trúc hơn (cờ, mặc định, trợ giúp), hãy sử dụng gói flag từ stdlib hoặc các thư viện bên ngoài như cobra.
os.Stdin, os.Stdout, os.Stderr
Đây là ba *os.File toàn cầu: bất cứ nơi nào io.Reader hoặc io.Writer được chấp nhận, bạn có thể vượt qua chúng.
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin) // echoBài tập
In đối số dòng lệnh đầu tiên (os.Args[1]). Nếu thiếu, hãy in 'manca argomento' và trả lại.
Giải pháp khả dụng sau 3 lần thử
Viết chuỗi 'ciao' vào tệp 'out.txt' bằng os.WriteFile (quyền 0644). Xử lý lỗi.
Giải pháp khả dụng sau 3 lần thử
Chỉ mục của TÊN CHƯƠNG TRÌNH trong os.Args là gì?
fmt.Println(os.Args[???])