我一直在尝试自己学习Go,但在尝试读取和写入普通文件时,我被难住了。
我可以到inFile, _:= os。Open(INFILE, 0,0),但实际上获取文件的内容没有意义,因为read函数以[]字节作为参数。
func (file *File) Read(b []byte) (n int, err Error)
我一直在尝试自己学习Go,但在尝试读取和写入普通文件时,我被难住了。
我可以到inFile, _:= os。Open(INFILE, 0,0),但实际上获取文件的内容没有意义,因为read函数以[]字节作为参数。
func (file *File) Read(b []byte) (n int, err Error)
当前回答
这是一个很好的版本(但请注意,ioutil自Go 1.16以来已弃用):
package main
import (
"io/ioutil";
)
func main() {
contents,_ := ioutil.ReadFile("plikTekstowy.txt")
println(string(contents))
ioutil.WriteFile("filename", contents, 0644)
}
其他回答
[]byte是字节数组的全部或部分的切片(类似于子字符串)。可以将切片看作一个值结构,它带有一个隐藏的指针字段,用于系统定位和访问数组(切片)的全部或部分,加上用于切片长度和容量的字段,您可以使用len()和cap()函数访问这些字段。
这里有一个工作的入门套件,它可以读取和打印二进制文件;您将需要更改inName字面值以引用系统上的一个小文件。
package main
import (
"fmt";
"os";
)
func main()
{
inName := "file-rw.bin";
inPerm := 0666;
inFile, inErr := os.Open(inName, os.O_RDONLY, inPerm);
if inErr == nil {
inBufLen := 16;
inBuf := make([]byte, inBufLen);
n, inErr := inFile.Read(inBuf);
for inErr == nil {
fmt.Println(n, inBuf[0:n]);
n, inErr = inFile.Read(inBuf);
}
}
inErr = inFile.Close();
}
这是一个很好的版本(但请注意,ioutil自Go 1.16以来已弃用):
package main
import (
"io/ioutil";
)
func main() {
contents,_ := ioutil.ReadFile("plikTekstowy.txt")
println(string(contents))
ioutil.WriteFile("filename", contents, 0644)
}
请注意。由于Go 1.16 ReadFile在os包中。
试试这个:
package main
import (
"io";
)
func main() {
contents,_ := io.ReadFile("filename");
println(string(contents));
io.WriteFile("filename", contents, 0644);
}
让我们列出一个与Go 1兼容的列表,其中包括在Go中读写文件的所有方法。
因为文件API最近发生了变化,大多数其他答案都不适合Go 1。他们也想念bufio,这很重要。
在下面的例子中,我通过从文件中读取并写入目标文件来复制一个文件。
从基础开始
package main
import (
"io"
"os"
)
func main() {
// open input file
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
// close fi on exit and check for its returned error
defer func() {
if err := fi.Close(); err != nil {
panic(err)
}
}()
// open output file
fo, err := os.Create("output.txt")
if err != nil {
panic(err)
}
// close fo on exit and check for its returned error
defer func() {
if err := fo.Close(); err != nil {
panic(err)
}
}()
// make a buffer to keep chunks that are read
buf := make([]byte, 1024)
for {
// read a chunk
n, err := fi.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
// write a chunk
if _, err := fo.Write(buf[:n]); err != nil {
panic(err)
}
}
}
这里我用os。打开和操作。创建它们是os.OpenFile的方便包装器。我们通常不需要直接调用OpenFile。
注意处理EOF。Read尝试在每次调用时填充buf,并返回io。EOF作为错误,如果它达到文件的结束这样做。在这种情况下,buf仍将保存数据。对Read的后续调用返回0作为读取的字节数和相同的io。EOF作为错误。任何其他错误都会导致恐慌。
使用bufio
package main
import (
"bufio"
"io"
"os"
)
func main() {
// open input file
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
// close fi on exit and check for its returned error
defer func() {
if err := fi.Close(); err != nil {
panic(err)
}
}()
// make a read buffer
r := bufio.NewReader(fi)
// open output file
fo, err := os.Create("output.txt")
if err != nil {
panic(err)
}
// close fo on exit and check for its returned error
defer func() {
if err := fo.Close(); err != nil {
panic(err)
}
}()
// make a write buffer
w := bufio.NewWriter(fo)
// make a buffer to keep chunks that are read
buf := make([]byte, 1024)
for {
// read a chunk
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
// write a chunk
if _, err := w.Write(buf[:n]); err != nil {
panic(err)
}
}
if err = w.Flush(); err != nil {
panic(err)
}
}
Bufio在这里只是充当缓冲区,因为我们与数据没有太多关系。在大多数其他情况下(特别是文本文件),bufio非常有用,它为我们提供了一个很好的API,可以轻松灵活地读写,同时它在幕后处理缓冲。
注意:以下代码适用于较旧的Go版本(Go 1.15及之前)。事情发生了变化(ioutil自Go 1.16以来已弃用)。关于新方法,看看这个答案。
使用ioutil
package main
import (
"io/ioutil"
)
func main() {
// read the whole file at once
b, err := ioutil.ReadFile("input.txt")
if err != nil {
panic(err)
}
// write the whole body at once
err = ioutil.WriteFile("output.txt", b, 0644)
if err != nil {
panic(err)
}
}
易如反掌!但只有在确定处理的不是大文件时才使用它。
你也可以使用FMT包:
package main
import "fmt"
func main(){
file, err := os.Create("demo.txt")
if err != nil {
panic(err)
}
defer file.Close()
fmt.Fprint(file, name)
}