我一直在努力学习Go,但我一直难以尝试从普通文件读取和写入.
我可以得到inFile, _ := os.Open(INFILE, 0, 0),但实际上获取文件的内容没有意义,因为read函数将a []byte作为参数.
func (file *File) Read(b []byte) (n int, err Error)
Run Code Online (Sandbox Code Playgroud)
Mos*_*afa 460
让我们创建一个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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我用os.Open和os.Create其周围方便包装os.OpenFile.我们通常不需要OpenFile直接打电话.
注意治疗EOF.Read尝试填写buf每个调用,io.EOF如果它到达文件末尾则返回错误.在这种情况下buf仍将保留数据.随后的调用Read返回零作为读取的字节数和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)
}
}
Run Code Online (Sandbox Code Playgroud)
bufio这里只是作为一个缓冲区,因为我们与数据没什么关系.在大多数其他情况下(特别是文本文件)bufio非常有用,它为我们提供了一个很好的API,可以轻松灵活地进行读写,同时它可以处理幕后缓冲.
运用 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)
}
}
Run Code Online (Sandbox Code Playgroud)
非常简单!但只有在你确定自己没有处理大文件时才使用它.
小智 48
这是一个很好的版本:
package main
import (
"io/ioutil";
)
func main() {
contents,_ := ioutil.ReadFile("plikTekstowy.txt")
println(string(contents))
ioutil.WriteFile("filename", contents, 0644)
}
Run Code Online (Sandbox Code Playgroud)
use*_*610 28
运用 io.Copy
package main
import (
"io"
"log"
"os"
)
func main () {
// open files r and w
r, err := os.Open("input.txt")
if err != nil {
panic(err)
}
defer r.Close()
w, err := os.Create("output.txt")
if err != nil {
panic(err)
}
defer w.Close()
// do the actual work
n, err := io.Copy(w, r)
if err != nil {
panic(err)
}
log.Printf("Copied %v bytes\n", n)
}
Run Code Online (Sandbox Code Playgroud)
如果你不喜欢重新发明轮子,该io.Copy和io.CopyN可以为你服务好.如果你检查 io.Copy函数的来源,它只不过是一个封装在Go库中的Mostafa解决方案之一(实际上是"基本的"解决方案).不过,他们使用的缓冲区比他大得多.
pet*_*rSO 10
[]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();
}
Run Code Online (Sandbox Code Playgroud)
使用较新的Go版本,可以轻松读取/写入文件.要从文件中读取:
package main
import (
"fmt"
"io/ioutil"
)
func main() {
data, err := ioutil.ReadFile("text.txt")
if err != nil {
return
}
fmt.Println(string(data))
}
Run Code Online (Sandbox Code Playgroud)
要写入文件:
package main
import "os"
func main() {
file, err := os.Create("text.txt")
if err != nil {
return
}
defer file.Close()
file.WriteString("test\nhello")
}
Run Code Online (Sandbox Code Playgroud)
这将覆盖文件的内容(如果不存在则创建新文件).
试试这个:
package main
import (
"io";
)
func main() {
contents,_ := io.ReadFile("filename");
println(string(contents));
io.WriteFile("filename", contents, 0644);
}
Run Code Online (Sandbox Code Playgroud)
从 Go 1.16 开始,使用os.ReadFile将文件加载到内存,并使用os.WriteFile从内存写入文件(ioutil.ReadFile现在调用os.ReadFile)。
小心,os.ReadFile因为它将整个文件读入内存。
package main
import "os"
func main() {
b, err := os.ReadFile("input.txt")
if err != nil {
log.Fatal(err)
}
// `data` contains everything your file does
// This writes it to the Standard Out
os.Stdout.Write(data)
// You can also write it to a file as a whole
err = os.WriteFile("destination.txt", b, 0644)
if err != nil {
log.Fatal(err)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
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)
}
Run Code Online (Sandbox Code Playgroud)