在复制实际文件时,使用bufio Reader/Writer 有什么理由吗?

huangapple go评论74阅读模式
英文:

Is there a reson to use bufio Reader/Writer when copying actual files?

问题

我正在为您翻译以下内容:

我有一个简单的代码,用于在两个实际文件之间进行复制。(它们位于同一磁盘上,但不确定是否相关。)

func copy(inPath, outPath string) {
    inFile, err := os.Open(inPath)
	if err != nil {
		return fmt.Errorf("无法打开输入文件 %q:%w", inPath, err)
	}
	defer inFile.Close()

	outFile, err := os.Create(outPath)
	if err != nil {
		return fmt.Errorf("无法创建输出文件 %q:%w", outPath, err)
	}
	defer outFile.Close()

    if _, err := io.Copy(inFile, outFile); err != nil {
		return fmt.Errorf("无法将文件 %q 复制到 %q:%w", inPath, outPath, err)
	}
}

现在我不确定是否应该使用 bufio 来读取器或写入器,或者两者都使用,或者都不使用。

也就是说,我是否应该像这样做:

func copy(inPath, outPath string) {
    inFile, err := os.Open(inPath)
	if err != nil {
		return fmt.Errorf("无法打开输入文件 %q:%w", inPath, err)
	}
	defer inFile.Close()

	outFile, err := os.Create(outPath)
	if err != nil {
		return fmt.Errorf("无法创建输出文件 %q:%w", outPath, err)
	}
	defer outFile.Close()

    if _, err := io.Copy(bufio.NewWriter(outFile), bufio.NewReader(inFile)); err != nil {
		return fmt.Errorf("无法将文件 %q 复制到 %q:%w", inPath, outPath, err)
	}
}

bufio 的文档并没有告诉我何时使用它以及何时不使用。

英文:

I am having a simple code that copies between two actual files. (They are on the same disk, but not sure if that is relevant.)

func copy(inPath, outPath string) {
    inFile, err := os.Open(inPath)
	if err != nil {
		return fmt.Errorf("cannot open input file on path %q: %w", inPath, err)
	}
	defer inFile.Close()

	outFile, err := os.Create(outPath)
	if err != nil {
		return fmt.Errorf("cannot create output file on path %q: %w", outPath, err)
	}
	defer outFile()

    if _, err := io.Copy(inFile, outFile); err != nil {
		return fmt.Errorf("cannot copy file %q to %q: %w", inPath, outPath, err)
	}
}

I am now not sure, if I should or should not be using bufio to either reader or writer or both or none.

That is, if I should do something like

func copy(inPath, outPath string) {
    inFile, err := os.Open(inPath)
	if err != nil {
		return fmt.Errorf("cannot open input file on path %q: %w", inPath, err)
	}
	defer inFile.Close()

	outFile, err := os.Create(outPath)
	if err != nil {
		return fmt.Errorf("cannot create output file on path %q: %w", outPath, err)
	}
	defer outFile()

    if _, err := io.Copy(bufio.NewWriter(outFile), bufio.NewReader(inFile)); err != nil {
		return fmt.Errorf("cannot copy file %q to %q: %w", inPath, outPath, err)
	}
}

The bufio documentation does not tell me at all when to use it and when not.

答案1

得分: 2

在这种情况下不要使用bufio。当给定一个*os.File目标时,io.Copy通过调用dest.ReadFrom(src)来复制文件。如果源文件也是*os.File,ReadFrom会在某些系统上调用操作系统来进行复制。

在没有可用的ReadFrom和其他优化的情况下,对于io.Copy的源和目标,使用bufio也没有任何好处。io.Copy的缓冲区大小为32k,而bufio的默认缓冲区大小为4K。因为当传递一个较大的缓冲区时,bufio类型会绕过自己的缓冲区,所以bufio类型除了分配一些额外的内存外,不会做任何其他操作。

英文:

Do not use bufio in this scenario. When given an *os.File destination, io.Copy copies the file by calling dest.ReadFrom(src). If the source is also an *os.File, ReadFrom calls the OS to do the copy on some systems.

In the case where ReadFrom and other optimizations are not available, there's still no benefit to using bufio for io.Copy sources and destinations. The io.Copy buffer size is 32k and the bufio default buffer sizes are 4K. Because the bufio types bypass their own buffers when passed a larger buffer, the bufio types don't do anything other than allocate some extra memory.

huangapple
  • 本文由 发表于 2022年3月21日 13:02:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/71553024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定