gpt4 book ai didi

file - io.Copy() 的稀疏文件很大

转载 作者:IT王子 更新时间:2023-10-29 00:55:18 24 4
gpt4 key购买 nike

我想将文件从一个地方复制到另一个地方,但问题是我要处理很多稀疏文件。

有没有什么(简单的)方法可以复制稀疏文件而不会在目的地变得很大?

我的基本代码:

out, err := os.Create(bricks[0] + "/" + fileName)
in, err := os.Open(event.Name)
io.Copy(out, in)

最佳答案

一些背景理论

请注意,io.Copy() 会通过管道传输原始字节——一旦您认为它将数据从 io.Reader 传输到 ,这就可以理解了io.Writer 对应提供了Read([]byte)Write([]byte)。因此,io.Copy() 绝对能够处理任何提供的源字节和绝对消耗它们的任何接收器。

另一方面,文件中漏洞的位置是一种“旁道”信息,“经典”系统调用(例如 read(2))向用户隐藏了这些信息。io.Copy() 无法以任何方式传达此类边信道信息。

IOW,最初,文件稀疏性只是在用户背后高效存储数据的想法。

所以,不,io.Copy() 本身无法处理稀疏文件。

怎么办

您需要更深入地使用 syscall 包和一些手动修补来实现所有这些。

要处理漏洞,您应该为 lseek(2) 系统调用使用 SEEK_HOLESEEK_DATA 特殊值,虽然正式非标准,由 all 支持major platforms .

不幸的是,不存在对那些“where”位置的支持既不在股票 syscall 包中(从 Go 1.8.1 开始)也不在 golang.org/x/sys树。

但不要害怕,有两个简单的步骤:

  1. 首先,股票syscall.Seek()实际上映射到lseek(2)在相关平台上。

  2. 接下来,您需要计算出 SEEK_HOLE 的正确值,并且SEEK_DATA 用于您需要支持的平台。

    Note that they are free to be different between different platforms!

    比如说,在我的 Linux 系统上我可以做一些简单的事情

    $ grep -E 'SEEK_(HOLE|DATA)' </usr/include/unistd.h 
    # define SEEK_DATA 3 /* Seek to next data. */
    # define SEEK_HOLE 4 /* Seek to next hole. */

    …计算出这些符号的值。

现在,比方说,你在你的包中创建了一个特定于 Linux 的文件包含类似的东西

// +build linux

const (
SEEK_DATA = 3
SEEK_HOLE = 4
)

然后将这些值与 syscall.Seek() 一起使用。

要传递给 syscall.Seek() 和 friend 的文件描述符可以使用 Fd() 方法从打开的文件中获取os.File 值。

读取时使用的模式是检测包含数据的区域,并从中读取数据——参见 this举个例子。

请注意,这涉及读取稀疏文件;但是如果你真的想将它们传输为稀疏的——也就是说,在保持它们的这个属性的情况下——情况就更复杂了:它似乎更不便携,所以一些研究和实验到期了。

在 Linux 上,您似乎可以尝试使用 fallocate(2)FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE 尝试在您正在写入的文件的末尾;如果那合法地失败了(使用 syscall.EOPNOTSUPP),您只需将您正在读取的漏洞所覆盖的尽可能多的归零 block 铲到目标文件中——希望如此操作系统会做正确的事情,并自行将它们变成一个洞。

请注意,一些文件系统根本不支持空洞——作为一个概念。一个例子是 FAT 家族中的文件系统。我要引导您的是,无法创建稀疏文件可能在您的情况下实际上是目标文件系统的属性。

您可能会找到 Go issue #13548 "archive/tar: add support for writing tar containing sparse files"引起兴趣。


请注意:您还可以考虑检查复制源文件的目标目录是否与源文件位于同一文件系统中,如果是这样,请使用 syscall.Rename()(在 POSIX 系统上)或 os.Rename() 只在不同目录之间移动文件 w/o实际上是在复制它的数据。

关于file - io.Copy() 的稀疏文件很大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43035271/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com