读取文件
读取大文本
/**
适用场景: 要读取的文件比较大
*/
func testReadBigDataFromFile() {
file, err := os.Open("F:/goworkspace/src/goStudy/file/1.txt")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
// 读取
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n')
if err == io.EOF {
//已经到达文件的末尾
break
}
fmt.Println(str)
}
}
- 例子适用于大文本文件,主要使用了 bufio.NewReader(file) 缓存区,能够加速获取数据
- os.Open(filePath) 打开一个存在的文件
- 成功打开文件后,记住要关闭:defer file.Close()
- reader.ReadString(’\n’) 以换行符为分割符从缓冲区中获取数据
- err == io.EOF 判断是否到达文件的末尾,如果遍历到文件的末尾会抛出io.EOF 错误
读取小文本
/**
应用场景: 读取数据量小的文件
*/
func testReadAllDataFromFile() {
filePath := "F:/goworkspace/src/goStudy/file/1.txt"
arr, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(arr))
}
- ioutil.ReadFile(filePath) 直接从文件中获取所有的数据,返回[]byte
写文件
-
文档: 前往
-
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
- os.OpenFile 是一个更一般行的文件打开函数。
- name 文件名,
- flag 打开的方式 ,
const (
O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
O_RDWR int = syscall.O_RDWR // 读写模式打开文件
O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件
O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在
O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/O
O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件
)
- perm 权限控制(仅适用于linux、unix、MACOS 等,不适合Windows)例如 0666等
向一个不存在的文件中,写入五行 hello world
func testWriteToNoExistFile() {
filePath := "F:/goworkspace/src/goStudy/file/2.txt"
file, err := os.OpenFile(filePath, os.O_CREATE | os.O_WRONLY , 0666)
if err != nil {
log.Fatal("打开文件出错》", err)
}
// 关闭文件
defer file.Close()
writer := bufio.NewWriter(file)
str := "hello world !\n"
for i:=0; i<5; i++ {
writer.WriteString(str)
}
//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
// 否则文件中不会有数据
writer.Flush()
}
- bufio.NewWriter(file) 获取一个写的缓冲区,加速写的速度
- writer.WriteString(str) 将字符串写到缓存区中
- writer.Flush() 将缓存区中的数据刷新到文件中,这样文件才有内容,如果不执行该函数,文件就没有内容
向一个已经存在的文件中,替换文件中内容
func testWriteToExistFile() {
filePath := "F:/goworkspace/src/goStudy/file/2.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_TRUNC , 0666)
if err != nil {
log.Fatal("打开文件出错》", err)
}
// 关闭文件
defer file.Close()
writer := bufio.NewWriter(file)
str := "你好,世界\n"
for i:=0; i<5; i++ {
writer.WriteString(str)
}
//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
// 否则文件中不会有数据
writer.Flush()
}
向一个已经存在的文件中,替换文件中内容
// 向一个已经存在的文件中,替换文件中内容
func testAppendWriteToExistFile() {
filePath := "F:/goworkspace/src/goStudy/file/2.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_APPEND , 0666)
if err != nil {
log.Fatal("打开文件出错》", err)
}
// 关闭文件
defer file.Close()
writer := bufio.NewWriter(file)
str := "hello world\n"
for i:=0; i<5; i++ {
writer.WriteString(str)
}
//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
// 否则文件中不会有数据
writer.Flush()
}
先读取文件内容,后追加写入数据
func testReadFileThenAppendWriteToExistFile() {
filePath := "F:/goworkspace/src/goStudy/file/2.txt"
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND , 0666)
if err != nil {
log.Fatal("打开文件出错》", err)
}
// 关闭文件
defer file.Close()
//读取数据
reader := bufio.NewReader(file)
for {
str, er := reader.ReadString('\n')
if er == io.EOF {
fmt.Println("文件已到末尾 》", er)
break
}
fmt.Println(str)
}
// 开始写入数据
writer := bufio.NewWriter(file)
str := "再次追加\n"
for i:=0; i<5; i++ {
writer.WriteString(str)
}
//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
// 否则文件中不会有数据
writer.Flush()
}
拷贝文件
/**
文件拷贝 :
可以使用到 io 包下的Copy函数
func Copy(dst Writer, src Reader) (written int64, err error)
*/
func testCopyFile(fromFile string, toFile string) (written int64, err error) {
fileFrom,err := os.Open(fromFile)
if err != nil {
fmt.Println("文件打开失败",err)
return 0, err
}
defer fileFrom.Close()
reader := bufio.NewReader(fileFrom)
fileTo,err := os.OpenFile(toFile, os.O_CREATE | os.O_WRONLY , 0666)
if err != nil {
fmt.Println("文件打开失败",err)
return 0, err
}
defer fileTo.Close()
writer := bufio.NewWriter(fileTo)
defer writer.Flush() // 这里必须要有,因为博主在第一次执行的时候发现文件有了,但是文件中的内容没有,虽然输出拷贝成功。 查看Copy函数的源码发现没有使用Flush() 函数。
//所以我们在拷贝完成后需要自己手动刷新一下。
return io.Copy(writer, reader)
}
- 使用到的函数 func Copy(dst Writer, src Reader) (written int64, err error)
- 文档地址:前往
- 先打开一个存在的文件获取输入流,然后打开一个不存在的文件(以新建,只写的方式)获取输出流。然后调用os.Copy() 函数进行拷贝
别忘记了只写刷新语句,不然拷贝后的文件没有内容,只有空文件
- 测试一下:
package main
import (
"os"
"fmt"
"bufio"
"io"
"io/ioutil"
"log"
)
func main() {
fromFilePath := "F:/goworkspace/src/goStudy/file/2.txt"
toFilePath := "F:/goworkspace/src/goStudy/file/3.txt"
_, err := testCopyFile(fromFilePath, toFilePath)
if err != nil {
fmt.Println("拷贝出错》", err)
} else {
fmt.Println("拷贝成功")
}
}