英文:
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_SET
在os常量中定义为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 (
"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) // 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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论