มาสร้างรายการที่เข้ากันได้กับ Go 1 ของวิธีการอ่านและเขียนไฟล์ใน Go
เนื่องจากไฟล์ API มีการเปลี่ยนแปลงเมื่อเร็ว ๆ นี้และคำตอบอื่น ๆ ส่วนใหญ่ไม่ทำงานกับ Go 1 พวกเขายังพลาด bufio
ซึ่ง IMHO สำคัญ
ในตัวอย่างต่อไปนี้ฉันคัดลอกไฟล์โดยอ่านจากมันและเขียนไปยังไฟล์ปลายทาง
เริ่มต้นด้วยพื้นฐาน
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)
}
}
}
ที่นี่ฉันใช้os.Open
และos.Create
สิ่งที่ล้อมรอบos.OpenFile
สะดวก โดยปกติเราไม่จำเป็นต้องโทรติดต่อOpenFile
โดยตรง
สังเกตการรักษา EOF Read
พยายามกรอกข้อมูลการbuf
โทรแต่ละครั้งและส่งกลับio.EOF
ข้อผิดพลาดหากถึงจุดสิ้นสุดไฟล์ในการดำเนินการดังกล่าว ในกรณีนี้buf
จะยังคงเก็บข้อมูล การเรียกครั้งต่อ ๆ ไปจะRead
ส่งกลับค่าศูนย์ตามจำนวนไบต์ที่อ่านและเหมือนกับio.EOF
ข้อผิดพลาด ข้อผิดพลาดอื่น ๆ จะนำไปสู่ความตื่นตระหนก
การใช้ 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
มันทำหน้าที่เป็นบัฟเฟอร์ที่นี่เพราะเราไม่มีอะไรเกี่ยวข้องกับข้อมูลมากนัก ในสถานการณ์อื่น ๆ ส่วนใหญ่ (โดยเฉพาะกับไฟล์ข้อความ) bufio
มีประโยชน์มากโดยให้API ที่ดีสำหรับการอ่านและการเขียนอย่างง่ายดายและยืดหยุ่นในขณะที่มันจัดการบัฟเฟอร์ด้านหลังฉาก
การใช้ 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)
}
}
ง่ายเหมือนพาย! แต่ใช้เฉพาะเมื่อคุณแน่ใจว่าคุณไม่ได้จัดการกับไฟล์ขนาดใหญ่