golang 读取文件
一、打开文件的四种方式
(1) 利用ioutil.ReadFile直接从文件读取到[]byte中
func Read0() (string){
f, err := ioutil.ReadFile("file/test")
if err != nil {
fmt.Println("read fail", err)
}
return string(f)
}
(2) 先从文件读取到file中,在从file读取到buf, buf在追加到最终的[]byte
func Read1() (string){
//获得一个file
f, err := os.Open("file/test")
if err != nil {
fmt.Println("read fail")
return ""
}
//把file读取到缓冲区中
defer f.Close()
var chunk []byte
buf := make([]byte, 1024)
for {
//从file读取到buf中
n, err := f.Read(buf)
if err != nil && err != io.EOF{
fmt.Println("read buf fail", err)
return ""
}
//说明读取结束
if n == 0 {
break
}
//读取到最终的缓冲区中
chunk = append(chunk, buf[:n]...)
}
return string(chunk)
//fmt.Println(string(chunk))
}
(3) 先从文件读取到file, 在从file读取到Reader中,从Reader读取到buf, buf最终追加到[]byte
//先从文件读取到file, 在从file读取到Reader中,从Reader读取到buf, buf最终追加到[]byte,这个排第三
func Read2() (string) {
fi, err := os.Open("file/test")
if err != nil {
panic(err)
}
defer fi.Close()
r := bufio.NewReader(fi)
var chunks []byte
buf := make([]byte, 1024)
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if 0 == n {
break
}
//fmt.Println(string(buf))
chunks = append(chunks, buf...)
}
return string(chunks)
//fmt.Println(string(chunks))
}
(4) 读取到file中,再利用ioutil将file直接读取到[]byte中
//读取到file中,再利用ioutil将file直接读取到[]byte中, 这是最优
func Read3() (string){
f, err := os.Open("file/test")
if err != nil {
fmt.Println("read file fail", err)
return ""
}
defer f.Close()
fd, err := ioutil.ReadAll(f)
if err != nil {
fmt.Println("read to fd fail", err)
return ""
}
return string(fd)
}
读取速度比较
方式四 > 方式一 > 方式三 > 方式四
二、写文件
(1) 使用 io.WriteString 写入文件
func Write0() {
fileName := "file/test1"
strTest := "测试测试"
var f *os.File
var err error
if CheckFileExist(fileName) { //文件存在
f, err = os.OpenFile(fileName, os.O_APPEND, 0666) //打开文件
if err != nil{
fmt.Println("file open fail", err)
return
}
}else { //文件不存在
f, err = os.Create(fileName) //创建文件
if err != nil {
fmt.Println("file create fail")
return
}
}
//将文件写进去
n, err1 := io.WriteString(f, strTest)
if err1 != nil {
fmt.Println("write error", err1)
return
}
fmt.Println("写入的字节数是:", n)
}
(2) 使用 ioutil.WriteFile 写入文件
func Write1() {
fileName := "file/test2"
strTest := "测试测试"
var d = []byte(strTest)
err := ioutil.WriteFile(fileName, d, 0666)
if err != nil {
fmt.Println("write fail")
}
fmt.Println("write success")
}
(3) 使用 File(Write,WriteString) 写入文件
func Write2() {
fileName := "file/test3"
strTest := "测试测试"
var d1 = []byte(strTest)
f, err3 := os.Create(fileName) //创建文件
if err3 != nil{
fmt.Println("create file fail")
}
defer f.Close()
n2, err3 := f.Write(d1) //写入文件(字节数组)
fmt.Printf("写入 %d 个字节n", n2)
n3, err3 := f.WriteString("writesn") //写入文件(字节数组)
fmt.Printf("写入 %d 个字节n", n3)
f.Sync()
}
(4) 使用 bufio.NewWriter 写入文件
func Write3() {
fileName := "file/test3"
f, err3 := os.Create(fileName) //创建文件
if err3 != nil{
fmt.Println("create file fail")
}
w := bufio.NewWriter(f) //创建新的 Writer 对象
n4, err3 := w.WriteString("bufferedn")
fmt.Printf("写入 %d 个字节n", n4)
w.Flush()
f.Close()
}
三、检测文件是否存在
func CheckFileExist(fileName string) bool {
_, err := os.Stat(fileName)
if os.IsNotExist(err) {
return false
}
return true
}
四、逐行读取文件
f, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer f.Close()
rd := bufio.NewReader(f)
for {
line, err := rd.ReadString('\n') //以'\n'为结束符读入一行
if err != nil || io.EOF == err {
break
}
fmt.Println(line)
}
五、os.openfile大文件件方式和模式
方式
// Flags to OpenFile wrapping those of the underlying system. Not all
// flags may be implemented on a given system.
const (
// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
// 只读模式
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
// 只写模式
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
// 可读可写
O_RDWR int = syscall.O_RDWR // open the file read-write.
// The remaining values may be or'ed in to control behavior.
// 追加内容
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
// 创建文件,如果文件不存在
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
// 与创建文件一同使用,文件必须存在
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist.
// 打开一个同步的文件流
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
// 如果可能,打开时缩短文件
O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened.
)
模式
// The defined file mode bits are the most significant bits of the FileMode.
// The nine least-significant bits are the standard Unix rwxrwxrwx permissions.
// The values of these bits should be considered part of the public API and
// may be used in wire protocols or disk representations: they must not be
// changed, although new bits might be added.
const (
// The single letters are the abbreviations
// used by the String method's formatting.
// 文件夹模式
ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directory
// 追加模式
ModeAppend // a: append-only
// 单独使用
ModeExclusive // l: exclusive use
// 临时文件
ModeTemporary // T: temporary file; Plan 9 only
// 象征性的关联
ModeSymlink // L: symbolic link
// 设备文件
ModeDevice // D: device file
// 命名管道
ModeNamedPipe // p: named pipe (FIFO)
// Unix 主机 socket
ModeSocket // S: Unix domain socket
// 设置uid
ModeSetuid // u: setuid
// 设置gid
ModeSetgid // g: setgid
// UNIX 字符串设备,当设备模式是设置unix
ModeCharDevice // c: Unix character device, when ModeDevice is set
// 粘性的
ModeSticky // t: sticky
// 非常规文件;对该文件一无所知
ModeIrregular // ?: non-regular file; nothing else is known about this file
// bit位遮盖,不变的文件设置为none
// Mask for the type bits. For regular files, none will be set.
ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular
// 权限位
ModePerm FileMode = 0777 // Unix permission bits
)
创建一个文件并追加
package main
import (
"os"
)
func main() {
fname := "/tmp/t.txt"
f, err := os.OpenFile(fname, os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend|os.ModePerm)
if err != nil {
fmt.Println(err)
}
f.WriteString("test")
f.Close()
}
参考链接:
https://www.jianshu.com/p/711c453bff16
https://studygolang.com/articles/282
https://www.cnblogs.com/landv/p/13140156.html