文件读写
文件读取方法
- io/ioutil 包的 ReadFile 函数:直接读取整个文件的内容到内存中,适用于读取小文件或者将整个文件内容加载到内存中。
- os 包的 Open 和 Read 函数:以文件句柄的形式逐个字节或者指定大小读取文件内容,适用于读取大文件或者按需读取文件内容。
- bufio 包的 Scanner 结构:逐行读取文件内容,适用于按行读取文本文件。
文件写入方法
- io/ioutil 包的 WriteFile 函数:将指定内容一次性写入到文件中,适用于写入小数据量的文件。
- os 包的 OpenFile 和 Write 函数:以文件句柄的形式逐个字节或者指定大小写入文件内容,适用于写入大文件或者按需写入文件内容。
- bufio 包的 Writer 结构:提供缓冲写入功能,适用于频繁的写入操作和提高写入性能。
文件复制
读取复制文件名
// Package _case /*
package _case
import (
"fmt"
"log"
"os"
"strings"
)
// 源文件目录
const sourceDir = "source-file/"
const destDir = "dest-file/"
func getFiles(dir string) []string {
fs, err := os.ReadDir(dir) //os.ReadDir 函数读取目录
if err != nil {
log.Fatal(err)
}
list := make([]string, 0)
for _, f := range fs {
if f.IsDir() { //判断文件或目录 目录返回true 文件返回false
continue
}
//使用 strings.Trim 来处理文件路径,最后将每个文件的完整路径添加到一个字符串切片中,并返回这个切片
fullName := strings.Trim(dir, "/") + "/" + f.Name()
// [source-file/R-C.jpg]
// [source-file/R-C.jpg source-file/v2-bc37af7fb922c7a037832d0310c48fae_720w.jpg]
// [source-file/R-C.jpg source-file/v2-bc37af7fb922c7a037832d0310c48fae_720w.jpg source-file/屏幕截图 2023-07-24 141151.png]
list = append(list, fullName)
fmt.Println(list)
}
return list
}
根据文件名进行复制
package _case
import (
"io"
"log"
"os"
"path"
)
// CopyDirToDir 拷贝文件目录
func CopyDirToDir() {
list := getFiles(sourceDir) //被拷贝的文件目录
for _, f := range list {
_, name := path.Split(f) //接收一个文件路径作为参数,并返回路径中的两部分
destFileName := destDir + "copy/" + name //拷贝文件到copy目录
//复制文件
COPYFile(f, destFileName)
}
}
// COPYFile 复制文件
func COPYFile(srcName, destName string) (int64, error) {
src, err := os.Open(srcName) //打开源文件
if err != nil {
log.Fatal(err)
}
defer src.Close() //使用完后关闭
dst, err := os.OpenFile(destName, os.O_CREATE|os.O_WRONLY, 0644) //打开目标文件,设置可创建可写
if err != nil {
log.Fatal(err)
}
defer dst.Close()
return io.Copy(dst, src) //使用io.copy复制
}
一次性读取文件内容并写入新文件
package _case
import (
"log"
"os"
"path"
)
//一次性读取文件内容并写入新文件
func ReadWriteFiles() {
list := getFiles(sourceDir)
for _, f := range list {
bytes, err := os.ReadFile(f) //bytes为文件内容
if err != nil {
log.Fatal(err)
}
_, name := path.Split(f) //将目录名和文件名分开
destName := destDir + "normal/" + name //设置复制文件路径
err = os.WriteFile(destName, bytes, 0644) //将文件内容复制到指定位置
if err != nil {
return
}
}
}
分片读取文件内容分步写入新文件
package _case
import (
"io"
"log"
"os"
"path"
)
//分片读取文件内容分步写入新文件
func OneSideReadWriteToDest() {
list := getFiles(sourceDir)
for _, l := range list {
_, name := path.Split(l)
destFileName := destDir + "one-side/" + name
//文件写入
OneSideReadWrite(l, destFileName)
}
}
func OneSideReadWrite(srcName, destName string) {
src, err := os.Open(srcName)
if err != nil {
log.Fatal(err)
}
defer src.Close()
dst, err := os.OpenFile(destName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
log.Fatal(err)
}
defer dst.Close()
buf := make([]byte, 1024)
for {
n, err := src.Read(buf) //将读取的字节存储在buf中
if err != nil && err != io.EOF {
log.Fatal(err)
}
if n == 0 {
break
}
dst.Write(buf[:n]) //写入内容
}
}
文件按行读取
第一种方式
package _case
import (
"fmt"
"io"
"log"
"os"
"strings"
)
// README 以README文件为读取对象
const README = "README.md"
// ReadLine 一次性读取文件
// 按行拆分并打印
func ReadLine1() {
fileHandler, err := os.OpenFile(README, os.O_RDONLY, 0666)
if err != nil {
return
}
defer fileHandler.Close()
bytes, err := io.ReadAll(fileHandler)
if err != nil {
log.Fatal(err)
}
list := strings.Split(string(bytes), "\n")
for _, l := range list {
fmt.Println(l)
}
}
第二种方法
// ReadLine2 bufio 通过对io模块的封装,提供了数据的缓冲功能,能一定程度上减少大数据读写带来的开销
// 当发起读写操作时,会尝试从缓冲区读取数据,缓冲区没有数据后,才会从数据源获取数据
func ReadLine2() {
fileHandler, err := os.OpenFile(README, os.O_RDONLY, 0666)
if err != nil {
return
}
defer fileHandler.Close()
reader := bufio.NewReader(fileHandler) //bufio.NewReader 是 Go 语言中用于创建一个带有缓冲区的读取器的函数
for {
line, err := reader.ReadString('\n')
if err != io.EOF {
break
}
fmt.Println(line)
}
}
第三种方法
// ReadLine3 通过scanner 按行读取
// 单行默认64k
func ReadLine3() {
fileHandler, err := os.OpenFile(README, os.O_RDONLY, 0666)
if err != nil {
return
}
defer fileHandler.Close()
scanner := bufio.NewScanner(fileHandler)
for scanner.Scan() {
line := scanner.Text()
fmt.Println(line)
}
}