Rumah > Artikel > pembangunan bahagian belakang > Operasi membaca fail Golang: petua membaca fail besar dengan cepat
Operasi membaca fail Golang: Petua untuk membaca fail besar dengan cepat, contoh kod khusus diperlukan
Dalam pengaturcaraan Golang, membaca fail adalah operasi yang sangat biasa. Tetapi apabila fail besar perlu dibaca, ia biasanya merupakan operasi yang memakan masa dan sumber. Oleh itu, cara membaca fail besar dengan cepat adalah topik yang patut dibincangkan. Artikel ini akan memperkenalkan cara menggunakan ciri Golang dan beberapa teknik untuk membaca fail besar dengan cepat dan memberikan contoh kod khusus.
Di Golang, cara paling biasa untuk membaca fail ialah menggunakan operasi baca buffer yang disediakan oleh pakej bufio. bufio menyediakan tiga struktur: Pembaca, Penulis dan Pengimbas. Antaranya, Reader ialah struktur yang digunakan untuk bacaan buffer. Apabila menggunakan Pembaca untuk membaca fail, anda boleh menetapkan saiz penimbal dan meletakkan data baca ke dalam penimbal, sekali gus mengurangkan bilangan bacaan. Kod tersebut dilaksanakan seperti berikut:
func ReadFileWithBufio(filePath string) ([]byte, error) { file, err := os.Open(filePath) if err != nil { return nil, err } defer file.Close() reader := bufio.NewReader(file) buffer := bytes.NewBuffer(make([]byte, 0)) for { line, isPrefix, err := reader.ReadLine() buffer.Write(line) if err != nil { if err == io.EOF { break } return nil, err } if !isPrefix { buffer.WriteString(" ") } } return buffer.Bytes(), nil }
Dalam kod di atas, kaedah ReadLine() bufio.Reader digunakan untuk membaca fail. Baca satu baris data pada satu masa dan tentukan sama ada terdapat data berikutnya. Jika terdapat data berikutnya, teruskan membaca data berikutnya dan masukkan ke dalam buffer. Jika tiada data seterusnya, data baca dimasukkan ke dalam penimbal dan aksara baris baharu ditambah. Apabila bacaan fail selesai, data yang disimpan dalam penimbal dikembalikan.
Menggunakan pakej bufio untuk membaca fail mempunyai kelebihan berikut:
Pustaka standard Golang juga menyediakan pakej ioutil, yang mengandungi operasi yang berkaitan dengan pembacaan fail. Menggunakan kaedah ReadFile() bagi pakej ioutil, keseluruhan fail boleh dibaca sekali gus. Kaedah ini biasanya sesuai apabila saiz fail tidak melebihi beberapa G, kerana membaca keseluruhan fail pada satu masa memerlukan ruang memori yang agak besar. Kod tersebut dilaksanakan seperti berikut:
func ReadFileWithIOUtil(filePath string) ([]byte, error) { data, err := ioutil.ReadFile(filePath) if err != nil { return nil, err } return data, nil }
Dalam kod di atas, kaedah ReadFile() bagi pakej ioutil digunakan untuk membaca keseluruhan fail. Apabila bacaan fail selesai, kandungan fail dikembalikan dalam jenis []bait.
Kelebihan menggunakan pakej ioutil untuk membaca fail ialah: kodnya ringkas, mudah difahami dan digunakan. Kelemahannya ialah: apabila saiz fail besar, ia perlu menduduki sejumlah besar ruang memori, yang boleh menyebabkan limpahan memori dengan mudah. Oleh itu, kaedah ini hanya disyorkan apabila membaca fail kecil.
Apabila fail yang hendak dibaca sangat besar, atau lebih besar daripada kapasiti memori, menggunakan teknologi goroutine untuk membaca fail dalam ketulan mungkin merupakan pilihan terbaik. Keseluruhan fail boleh dibahagikan kepada beberapa bahagian, dan goroutine boleh didayakan untuk membaca daripada setiap bahagian. Sebagai contoh, kod berikut membahagikan fail 1GB kepada 100 ketulan, setiap ketulan bersaiz 10MB.
const fileChunk = 10 * (1 << 20) // 10 MB func ReadFileWithMultiReader(filePath string) ([]byte, error) { file, err := os.Open(filePath) if err != nil { return nil, err } defer file.Close() fileInfo, _ := file.Stat() fileSize := fileInfo.Size() if fileSize < fileChunk { return ioutil.ReadFile(filePath) } buffer := bytes.NewBuffer(make([]byte, 0)) chunkSize := int(math.Ceil(float64(fileSize) / float64(100))) for i := 0; i < 100; i++ { offset := int64(i * chunkSize) readSize := int(math.Min(float64(chunkSize), float64(fileSize-int64(i*chunkSize)))) buf := make([]byte, readSize) file.ReadAt(buf, offset) go func(b []byte) { buffer.Write(b) }(buf) } time.Sleep(time.Millisecond * 100) return buffer.Bytes(), nil }
Dalam kod di atas, mula-mula kira saiz fail yang hendak dibaca Jika saiz fail kurang daripada 10MB, gunakan ioutil untuk membaca keseluruhan fail sekali gus, jika tidak fail akan dibahagikan kepada 100 blok. Saiz setiap blok ialah fileSize/100. Kemudian buat gelung 100 goroutine, baca fail dalam blok satu demi satu, dan tulis data baca ke dalam penimbal. Akhir sekali, gunakan kaedah time.Sleep() untuk melengkapkan semua pelaksanaan goroutine dan mengembalikan data yang disimpan dalam penimbal.
Kelebihan menggunakan kaedah ini untuk membaca fail ialah:
Ringkasan
Melalui pengenalan artikel ini, kita dapat melihat bahawa teknik yang berbeza boleh digunakan untuk meningkatkan kecekapan membaca fail untuk saiz fail dan kaedah membaca yang berbeza. Untuk fail yang lebih kecil, kami boleh menggunakan pakej ioutil untuk bacaan sekali sahaja. Untuk fail yang lebih besar, anda boleh menggunakan pakej bufio untuk bacaan buffer, atau goroutine untuk bacaan chunk. Dalam projek sebenar, anda mesti memilih kaedah bacaan yang paling sesuai mengikut situasi sebenar untuk meningkatkan prestasi dan kebolehpercayaan program.
Atas ialah kandungan terperinci Operasi membaca fail Golang: petua membaca fail besar dengan cepat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!