io.Copy() erase the Reader content

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

io.Copy() erase the Reader content

问题

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

func main() {
	file, err := os.Open("HelloWorld")
	if nil != err {
		fmt.Println(err)
	}
	defer file.Close()

	fileTo, err := os.Create("fileTo")
	if nil != err {
		fmt.Println(err)
	}
	defer fileTo.Close()

	_, err = io.Copy(fileTo, file)
	if nil != err {
		fmt.Println(err)
	}

	fileByteOne, err := ioutil.ReadAll(file)
	if nil != err {
		fmt.Println(err)
	}

	fmt.Println(fileByteOne)
}

io.Copy()函数会擦除文件内容,输出结果为:

[]

Copy(dst Writer, src Reader)函数会从src复制到dst,它会擦除src的内容。有没有办法避免擦除呢?

英文:
	package main

	import (
		"fmt"
		"io"
		"io/ioutil"
		"os"
	)

	func main() {
		file, err := os.Open("HelloWorld")
		if nil != err {
			fmt.Println(err)
		}
		defer file.Close()

		fileTo, err := os.Create("fileTo")
		if nil != err {
			fmt.Println(err)
		}
		defer file.Close()

		_, err = io.Copy(fileTo, file)
		if nil != err {
			fmt.Println(err)
		}

		fileByteOne, err := ioutil.ReadAll(file)
		if nil != err {
			fmt.Println(err)
		}

		fmt.Println(fileByteOne)
	}

io.Copy() will erase the file content, the output is :

[]

Copy(dst Writer, src Reader) copies from src to dst, it will erase the src content. Is there
any way to avoid erasing?

答案1

得分: 4

io.Copy(fileTo, file)不会擦除文件内容,但它会将读取位置移动到文件末尾(EOF),这意味着下一个ioutil.ReadAll()将从文件末尾开始读取。你可以在ioutil.ReadAll()之前关闭并重新打开file。另外,你有两个defer file.Close()实例,第二个应该是defer fileTo.Close()。或者,更简单的方法是使用SectionReader.Seek()进行重置,正如PeterSO答案中所建议的那样。

 _, err = file.Seek(0, io.SeekStart)

这也在GoByExamples Reading Files中有说明:

没有内置的倒带功能,但Seek(0, 0)可以实现这个目的。

os.SEEK_SETos常量中定义为0

const SEEK_SET int = 0 // 相对于文件起始位置的偏移量

现在(2020年)已被弃用,并被io.SeekStart取代。另请参阅“Golang, a proper way to rewind file pointer”。

英文:

<!-- language-all: go -->

> io.Copy(fileTo, file) will erase the file content

It won't. But it will move the read position to EOF, meaning the next ioutil.ReadAll() will start at ... EOF.

You could close it and re-open 'file'before your ioutil.ReadAll().

By the way, you have two defer file.Close() instances: the second one should be defer fileTo.Close().
Or, simpler, reset it with a SectionReader.Seek(), as suggested by PeterSO's answer.

 _, err = file.Seek(0, io.SeekStart)

It is also illustrated in GoByExamples Reading Files:

> There is no built-in rewind, but Seek(0, 0) accomplishes this.

(os.SEEK_SET is define in os constants, as 0)

const SEEK_SET int = 0 // seek relative to the origin of the file

Now (2020) deprecated and replaced with io.SeekStart.
See also "Golang, a proper way to rewind file pointer".

答案2

得分: 2

从文件的末尾重置到文件的开头,可以使用 seek 函数。例如:

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

func main() {
	file, err := os.Open("HelloWorld")
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()

	fileTo, err := os.Create("fileTo")
	if err != nil {
		fmt.Println(err)
	}
	defer fileTo.Close()

	_, err = io.Copy(fileTo, file)
	if err != nil {
		fmt.Println(err)
	}

	_, err = file.Seek(0, os.SEEK_SET) // 文件开头
	if err != nil {
		fmt.Println(err)
	}
	fileByteOne, err := ioutil.ReadAll(file)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(fileByteOne)
}

输出结果:

[72 101 108 108 111 44 32 87 111 114 108 100 33 10]
英文:

Reset from the end of the file to the start of the file with a seek. For example.

package main

import (
	&quot;fmt&quot;
	&quot;io&quot;
	&quot;io/ioutil&quot;
	&quot;os&quot;
)

func main() {
	file, err := os.Open(&quot;HelloWorld&quot;)
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()

	fileTo, err := os.Create(&quot;fileTo&quot;)
	if err != nil {
		fmt.Println(err)
	}
	defer fileTo.Close()

	_, err = io.Copy(fileTo, file)
	if err != nil {
		fmt.Println(err)
	}

	_, err = file.Seek(0, os.SEEK_SET) // start of file
	if err != nil {
		fmt.Println(err)
	}
	fileByteOne, err := ioutil.ReadAll(file)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(fileByteOne)
}

Output:

[72 101 108 108 111 44 32 87 111 114 108 100 33 10]

huangapple
  • 本文由 发表于 2014年4月24日 13:46:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/23260738.html
匿名

发表评论

匿名网友

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

确定