go - 文件的copy与读写

文件读写

文件读取方法

  1. io/ioutil 包的 ReadFile 函数:直接读取整个文件的内容到内存中,适用于读取小文件或者将整个文件内容加载到内存中。
  2. os 包的 Open 和 Read 函数:以文件句柄的形式逐个字节或者指定大小读取文件内容,适用于读取大文件或者按需读取文件内容。
  3. bufio 包的 Scanner 结构:逐行读取文件内容,适用于按行读取文本文件。

文件写入方法

  1. io/ioutil 包的 WriteFile 函数:将指定内容一次性写入到文件中,适用于写入小数据量的文件。
  2. os 包的 OpenFile 和 Write 函数:以文件句柄的形式逐个字节或者指定大小写入文件内容,适用于写入大文件或者按需写入文件内容。
  3. 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)
	}
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值