简体   繁体   English

如何动态获取 Go 中的文件长度?

[英]How to get file length in Go dynamically?

I have the following code snippet:我有以下代码片段:

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")
}

However, I wish to know a small modification.但是,我想知道一个小的修改。 When the size of file reaches a certain threshold I want to close it and open a new file.当文件大小达到某个阈值时,我想关闭它并打开一个新文件。 And that too in compressed format.这也是压缩格式。

For example:例如:

Assume a database has 10 rows each row is 50 bytes.假设一个数据库有 10 行,每行 50 个字节。

Assume compression factor is 2, ie 1 row of 50 bytes is compressed to 25 bytes.假设压缩因子为 2,即 1 行 50 字节压缩为 25 字节。

Assume a file size limit is 50 bytes.假设文件大小限制为 50 字节。

Which means after every 2 records I should close the file and open a new file.这意味着每 2 条记录后我应该关闭文件并打开一个新文件。

How to keep track of the file size while its still open and still writing compressed documents to it?如何在文件仍然打开并仍在向其写入压缩文档时跟踪文件大小?

gzip.NewWriter takes a io.Writer . gzip.NewWriter采用io.Writer It is easy to implement custom io.Writer that does what you want.很容易实现自定义io.Writer来满足您的需求。

Eg Playground例如游乐场

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)
}

Note: You will need to handle few edge cases like what if len(data) is greater than the maxLimit .注意:您将需要处理一些边缘情况,例如如果len(data)大于maxLimit And may be you don't want to split a record across files.并且您可能不想跨文件拆分记录。

You can use the os.File.Seek method to get your current position in the file, which as you're writing the file will be the current file size in bytes.您可以使用os.File.Seek方法在文件中获取当前的 position,当您写入文件时,它将是当前文件大小(以字节为单位)。

For example:例如:

package main

import (
    "fmt"
    "os"
)

func main() {
    words := []string{"this", "is", "a", "test"}

    fd, err := os.Create("testfile.txt")
    if err != nil {
        panic(err)
    }
    defer fd.Close()

    for _, word := range words {
        fd.Write([]byte(word))
        fd.Write([]byte(" "))
        pos, err := fd.Seek(0, os.SEEK_CUR)
        if err != nil {
            panic(err)
        }

        fmt.Printf("file position: %d\n", pos)
    }
}

Which outputs:哪个输出:

file position: 5
file position: 8
file position: 10
file position: 15

And we can confirm with wc :我们可以用wc确认:

$ wc -c testfile.txt
15 testfile.txt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM