(原文地址:https://blog.gm7.org/%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E5%BA%93/03.%E7%BC%96%E7%A8%8B%E5%BC%80%E5%8F%91/GO/02.GO%E5%B8%B8%E7%94%A8%E5%AE%9E%E4%BE%8B.html)
读
按字节读取文件
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, _ := os.Open("c:\\windows\\win.ini") //打开文件。这里file返回的是文件的指针,不是具体值。
fmt.Println("os.Open返回文件指针:", file)
defer file.Close() //在执行完函数,就关闭文件句柄。
//字节类型的集合,byte是uint8的别名,所以在这里用[]uint8也是可以的。
buf := make([]byte, 1024)
var result string //用于存放最终的结果
for { //这里for是永真条件
count, err := file.Read(buf) //最多读取len(buf),即1024字节,并追加在集合buf中。
if err == io.EOF { //检测是否到结尾
break //文件读取结尾,就跳出循环
} else {
currBytes := buf[:count] //把buf缓冲区中的字节赋值给currBytes
result += string(currBytes)
}
}
fmt.Println(result)
}
借助ioutil来读取
这方法可以将文件所有字节一次性取出来,省去了使用字节循环读取的过程。
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
//这两句是不变的,获取文件的指针
file, _ := os.Open("c:\\windows\\win.ini")
defer file.Close()
byteRes, _ := ioutil.ReadAll(file) //返回byte类型,要用string转换一下输出
fmt.Println(string(byteRes))
}
仅使用ioutil
package main
import (
"fmt"
"io/ioutil"
)
func main() {
byteRes, _ := ioutil.ReadFile("c:\\windows\\win.ini") //返回byte类型,要用string转换一下输出
fmt.Println(string(byteRes))
}
利用scanner
有些时候,按字节不符合业务场景,比如读取文件里面的url,一行一个url,用scanner比较适合。
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, _ := os.Open("F:\\Codes\\Go\\url.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
//读到了,scan返回true
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
写
通过ioutil
读用到了ioutil.ReadFile,当然也有WriteFile。这个方法使用覆盖写入,如果有此文件,会清空文件写入,如果没有此文件,会根据权限来创建文件。
要注意一点就是os.FileMode,在Linux中,rwx用4,2,1来代表,相加为7则为最高权限可读可写可执行,所以赋予777是最高权限,666则为可读可写。第一个6代表文件所有者本身的权限,第二个6代表同组的用户权限,第三个6代表其他用户的权限。
package main
import (
"io/ioutil"
)
func main() {
data := "12312312313123"
ioutil.WriteFile("test.txt", []byte(data), 0666) //0666是可读可写
}
通过file句柄
os.OpenFile(name string, flag int , prem FileMove)方法,可以指定额外的读写方法和文件权限参数。
一下几个常用的flag值:
- os.O_CREATE: create if none exists 不存在则创建
- os.O_RDONLY: read-only 只读
- os.O_WRONLY: write-only 只写
- os.O_RDWR: read-write 可读可写
- os.O_TRUNC: truncate when opened 文件长度截为0:即清空文件
- os.O_APPEND: append 追加新数据到文件 ```go package main
import ( “os” )
func main() { //按权限打开句柄,可读可写,追加,不存在则创建 file, _ := os.OpenFile(“test1.txt”, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) defer file.Close()
data := "111111111111111111111"
file.Write([]byte(data)) //按字节写入
file.WriteString("2222222222222222222") //按字符串写入
}
![image.png](https://cdn.nlark.com/yuque/0/2022/png/22872200/1655713238051-44957bd2-52c8-463d-8bd5-bbbd998e3654.png#clientId=u5263a180-96fc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=247&id=u85beddc1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=247&originWidth=608&originalType=binary&ratio=1&rotation=0&showTitle=false&size=13920&status=done&style=none&taskId=u6ef591b4-0284-40e7-a80d-5ffab3355aa&title=&width=608)
<a name="cgWpI"></a>
## 通过ioutil
这个方法比上面一种,只多了一行代码:
```go
import (
"bufio"
"os"
)
func main() {
//按权限打开句柄,可读可写,追加,不存在则创建
file, _ := os.OpenFile("test2.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
defer file.Close()
w := bufio.NewWriter(file)
data := "333333333333"
w.Write([]byte(data)) //按字节写入
w.WriteString("4444444444444444") //按字符串写入
w.Flush() //情况缓存
}