Go實戰--golang中讀寫檔案的幾種方式
讀寫檔案應該是在開發過程中經常遇到的,今天要跟大家一起分享的就是在golang的世界中,如何讀寫檔案。
使用io/ioutil進行讀寫檔案
其中提到了兩個方法: func ReadFile
func ReadFile(filename string) ([]byte, error)
ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported.
func WriteFile
func WriteFile(filename string, data []byte, perm os.FileMode) error
WriteFile writes data to a file named by filename. If the file does not exist, WriteFile creates it with permissions perm; otherwise WriteFile truncates it before writing.
讀檔案:
package main import ( "fmt" "io/ioutil" ) func main() { b, err := ioutil.ReadFile("test.log") if err != nil { fmt.Print(err) } fmt.Println(b) str := string(b) fmt.Println(str) }
寫檔案:
package main
import (
"io/ioutil"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
d1 := []byte("hello\ngo\n")
err := ioutil.WriteFile("test.txt", d1, 0644)
check(err)
}
使用os進行讀寫檔案
首先要注意的就是兩個開啟檔案的方法: func Open
func Open(name string) (*File, error)
Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY. If there is an error, it will be of type *PathError.
讀檔案:
fi, err := os.Open(path)
if err != nil {
panic(err)
}
defer fi.Close()
func OpenFile 需要提供檔案路徑、開啟模式、檔案許可權
func OpenFile(name string, flag int, perm FileMode) (*File, error)
OpenFile is the generalized open call; most users will use Open or Create instead. It opens the named file with specified flag (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, methods on the returned File can be used for I/O. If there is an error, it will be of type *PathError.
讀檔案:
package main
import (
"log"
"os"
)
func main() {
f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
讀方法
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
f, err := os.Open("/tmp/dat")
check(err)
b1 := make([]byte, 5)
n1, err := f.Read(b1)
check(err)
fmt.Printf("%d bytes: %s\n", n1, string(b1))
o2, err := f.Seek(6, 0)
check(err)
b2 := make([]byte, 2)
n2, err := f.Read(b2)
check(err)
fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))
o3, err := f.Seek(6, 0)
check(err)
b3 := make([]byte, 2)
n3, err := io.ReadAtLeast(f, b3, 2)
check(err)
fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))
_, err = f.Seek(0, 0)
check(err)
r4 := bufio.NewReader(f)
b4, err := r4.Peek(5)
check(err)
fmt.Printf("5 bytes: %s\n", string(b4))
f.Close()
}
寫方法
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
f, err := os.Create("/tmp/dat2")
check(err)
defer f.Close()
d2 := []byte{115, 111, 109, 101, 10}
n2, err := f.Write(d2)
check(err)
fmt.Printf("wrote %d bytes\n", n2)
n3, err := f.WriteString("writes\n")
fmt.Printf("wrote %d bytes\n", n3)
f.Sync()
w := bufio.NewWriter(f)
n4, err := w.WriteString("buffered\n")
fmt.Printf("wrote %d bytes\n", n4)
w.Flush()
}
幾種讀取檔案方法速度比較
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"time"
)
func read0(path string) string {
f, err := ioutil.ReadFile(path)
if err != nil {
fmt.Printf("%s\n", err)
panic(err)
}
return string(f)
}
func read1(path string) string {
fi, err := os.Open(path)
if err != nil {
panic(err)
}
defer fi.Close()
chunks := make([]byte, 1024, 1024)
buf := make([]byte, 1024)
for {
n, err := fi.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if 0 == n {
break
}
chunks = append(chunks, buf[:n]...)
}
return string(chunks)
}
func read2(path string) string {
fi, err := os.Open(path)
if err != nil {
panic(err)
}
defer fi.Close()
r := bufio.NewReader(fi)
chunks := make([]byte, 1024, 1024)
buf := make([]byte, 1024)
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if 0 == n {
break
}
chunks = append(chunks, buf[:n]...)
}
return string(chunks)
}
func read3(path string) string {
fi, err := os.Open(path)
if err != nil {
panic(err)
}
defer fi.Close()
fd, err := ioutil.ReadAll(fi)
return string(fd)
}
func main() {
file := "test.log"
start := time.Now()
read0(file)
t0 := time.Now()
fmt.Printf("Cost time %v\n", t0.Sub(start))
read1(file)
t1 := time.Now()
fmt.Printf("Cost time %v\n", t1.Sub(t0))
read2(file)
t2 := time.Now()
fmt.Printf("Cost time %v\n", t2.Sub(t1))
read3(file)
t3 := time.Now()
fmt.Printf("Cost time %v\n", t3.Sub(t2))
}