压缩 json 文件 >= 60MB 转到文件 tar.gz

问题描述 投票:0回答:1

当我压缩 >= 60MB 的 json 文件时,出现数据不足且只有 28MB 可用的错误。

func CreateTarGz(sourceDir, targetFile string) error {
    target, err := os.Create(targetFile)
    if err != nil {
        return err
    }
    defer target.Close()

    gw := gzip.NewWriter(target)
    defer gw.Close()

    tw := tar.NewWriter(gw)

    defer tw.Close()

    err = filepath.Walk(sourceDir, func(path string, info fs.FileInfo, err error) error {
        if err != nil {
            return err
        }

        // Tạo header cho tệp
        header, err := tar.FileInfoHeader(info, "")
        if err != nil {
            return err
        }

        header.Name = strings.TrimPrefix(strings.TrimPrefix(path, sourceDir), string(filepath.Separator))
        header.Size = info.Size()
        if err := tw.WriteHeader(header); err != nil {
            return err
        }
        if info.IsDir() {
            return nil
        }

        // Mở tệp
        file, err := os.Open(path)
        if err != nil {
            return err
        }
        defer file.Close()

        // Sử dụng bộ đệm để đọc tệp
        buf := make([]byte, 1024*1024*2)
        header.Size = info.Size()
        for {
            n, err := file.Read(buf)
            if err != nil && err != io.EOF {
                return err
            }
            if n == 0 {
                break
            }
            if _, err := tw.Write(buf[:n]); err != nil {
                log.Printf("failed to write %d bytes to tar for %s: %v", n, path, err)
                return err
            }
        }
        return nil
    })

    return err
}

我想从一个 json 文件 >= 60mb 的文件夹中压缩一个 tar.gz 文件,如何才能不出错。目前我只能写入28mb,其余的都缺少数据。

json go compression go-gin opa
1个回答
0
投票

👋。正如其他人在评论中指出的那样,您可以使用 os.Copy 来获取 WalkDir 循环内文件的所有字节。 我还注意到您正在尝试手动设置标题的名称和大小,但这已经由以下处理:

header, err := tar.FileInfoHeader(info, "")

尝试手动设置名称和大小也会对循环的第一次迭代(对于 sourceDir)产生负面影响,因为您将 sourceDir 修剪为空字符串,然后用空字符串覆盖标头的名称。

这是我根据您的代码编写的一个最小示例(我也在其中写了自己的评论):

fGzip, err := os.Create("baz.gzip")
if err != nil {
    panic(err)
}
defer fGzip.Close()

wGzip := gzip.NewWriter(fGzip)
defer wGzip.Close()

wTar := tar.NewWriter(wGzip)
defer wTar.Close()

err = filepath.Walk("./tmp", func(path string, info fs.FileInfo, err error) error {
    if err != nil {
        return err
    }

    // Create header for entry
    header, err := tar.FileInfoHeader(info, "")
    if err != nil {
        return err
    }
    if err := wTar.WriteHeader(header); err != nil {
        return err
    }

    // Don't try to write dir to Tar
    if info.IsDir() {
        return nil
    }

    // Write file to Tar
    b, err := os.ReadFile(path)
    if err != nil {
        return err
    }
    _, err = wTar.Write(b)
    if err != nil {
        return err
    }

    return nil
})
if err != nil {
    panic(err)
}

当我在 tmp 文件夹上运行它时:

+ tmp
  + bar
    - file1.txt
  + foo
    - file2.json

然后运行

tar -tzf baz.gzip
,我得到了预期的结果:

tmp/
bar/
file1.txt
foo/
file2.json
© www.soinside.com 2019 - 2024. All rights reserved.