我有以下代碼片段:
func main() {
// Some text we want to compress.
original := "bird and frog"
// Open a file for writing.
f, _ := os.Create("C:\\programs\\file.gz")
// Create gzip writer.
w := gzip.NewWriter(f)
// Write bytes in compressed form to the file.
while ( looping over database cursor) {
w.Write([]byte(/* the row from the database as obtained from cursor */))
}
// Close the file.
w.Close()
fmt.Println("DONE")
}
但是,我想知道一個小的修改。當檔案大小達到某個閾值時,我想關閉它并打開一個新檔案。這也是壓縮格式。
例如:
假設一個資料庫有 10 行,每行 50 個位元組。
假設壓縮因子為 2,即 1 行 50 位元組壓縮為 25 位元組。
假設檔案大小限制為 50 位元組。
這意味著每 2 條記錄后我應該關閉檔案并打開一個新檔案。
如何在檔案仍然打開并仍在向其寫入壓縮檔案時跟蹤檔案大小?
uj5u.com熱心網友回復:
gzip.NewWriter
需要一個io.Writer
. 很容易實作io.Writer
你想要的自定義。
例如游樂場
type MultiFileWriter struct {
maxLimit int
currentSize int
currentWriter io.Writer
}
func (m *MultiFileWriter) Write(data []byte) (n int, err error) {
if len(data) m.currentSize > m.maxLimit {
m.currentWriter = createNextFile()
}
m.currentSize = len(data)
return m.currentWriter.Write(data)
}
注意:您將需要處理一些邊緣情況,例如 what iflen(data)
大于maxLimit
. 并且您可能不想跨檔案拆分記錄。
uj5u.com熱心網友回復:
您可以使用該os.File.Seek
方法獲取檔案中的當前位置,在您寫入檔案時,該位置將是當前檔案大小(以位元組為單位)。
例如:
package main
import (
"compress/gzip"
"fmt"
"os"
)
func main() {
// Some text we want to compress.
lines := []string{
"this is a test",
"the quick brown fox",
"jumped over the lazy dog",
"the end",
}
// Open a file for writing.
f, err := os.Create("file.gz")
if err != nil {
panic(err)
}
// Create gzip writer.
w := gzip.NewWriter(f)
// Write bytes in compressed form to the file.
for _, line := range lines {
w.Write([]byte(line))
w.Flush()
pos, err := f.Seek(0, os.SEEK_CUR)
if err != nil {
panic(err)
}
fmt.Printf("pos: %d\n", pos)
}
// Close the file.
w.Close()
// The call to w.Close() will write out any remaining data
// and the final checksum.
pos, err := f.Seek(0, os.SEEK_CUR)
if err != nil {
panic(err)
}
fmt.Printf("pos: %d\n", pos)
fmt.Println("DONE")
}
哪個輸出:
pos: 30
pos: 55
pos: 83
pos: 94
pos: 107
DONE
我們可以確認wc
:
$ wc -c file.gz
107 file.gz
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/508328.html