golang之文件读写/复制/断点续传

 

目录

一、常用读取文件的三种方式

(1)利用os和file原生操作读文件

(2)使用bufio读取文件

(3)使用ioutil读取文件

二、常用写文件的三种方式

(1)利用os和file原生操作写文件

(2)使用bufio写文件

(3)使用ioutil写文件

三、常用复制文件的四种方式

(1)利用os和file原生操作复制文件

(2)使用bufio读写操作来复制文件

(3)使用ioutil读写操作来复制文件

(4)io.copy()来复制

​四、其他操作

(1)指定断点位置读写文件

(2)***文件复制之断点续传***

(3)遍历文件夹


一、常用读取文件的三种方式

(1)利用os和file原生操作读文件

golang之文件读写/复制/断点续传_第1张图片

注意:以open打开的方式是只读的

(2)使用bufio读取文件

golang之文件读写/复制/断点续传_第2张图片

注意:默认缓冲区大小是4096,这里我们可以自定义缓冲区大小

(3)使用ioutil读取文件

golang之文件读写/复制/断点续传_第3张图片

注意:ioutil是一次性读取整个文件,不适用于大文件读写操作,可能发生内存泄漏

二、常用写文件的三种方式

(1)利用os和file原生操作写文件

golang之文件读写/复制/断点续传_第4张图片

OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。

可指定选项【只读,只写,可读写,追加……】和模式【 ModePerm FileMode = 0777 // 覆盖所有Unix权限位】

下面列举了一些常用的 flag 文件处理参数:

  • O_RDONLY:只读模式打开文件;
  • O_WRONLY:只写模式打开文件;
  • O_RDWR:读写模式打开文件;
  • O_APPEND:写操作时将数据附加到文件尾部(追加);
  • O_CREATE:如果不存在将创建一个新文件;
  • O_EXCL:和 O_CREATE 配合使用,文件必须不存在,否则返回一个错误;
  • O_SYNC:当进行一系列写操作时,每次都要等待上次的 I/O 操作完成再进行;
  • O_TRUNC:如果可能,在打开时清空文件。

(2)使用bufio写文件

golang之文件读写/复制/断点续传_第5张图片

注意:bufio是写在缓冲区里面,一定要Flush,否则文件中没有数据

(3)使用ioutil写文件

golang之文件读写/复制/断点续传_第6张图片

三、常用复制文件的四种方式

(1)利用os和file原生操作复制文件

golang之文件读写/复制/断点续传_第7张图片

(2)使用bufio读写操作来复制文件

golang之文件读写/复制/断点续传_第8张图片

(3)使用ioutil读写操作来复制文件

golang之文件读写/复制/断点续传_第9张图片

(4)io.copy()来复制

golang之文件读写/复制/断点续传_第10张图片
四、其他操作

(1)指定断点位置读写文件

golang之文件读写/复制/断点续传_第11张图片

(2)***文件复制之断点续传***

如果在传输文件的过程中发生断电等情况,文件传输了一半后异常终止了,当恢复后不希望重新传输,而希望接着传输。

可创建一个临时文件用户保存当前已经传输的字节数,每次传输时先读取临时文件的记录。如传输完成则删除临时文件

//断点续传
func main() {
	srcFile := "D:/development/jetbrains/goland/workspace/src/Go-Player/hanru_package/a.jpg"
	distFile := "copy_"+srcFile[strings.LastIndex(srcFile, "/")+1:]
	tempFile := distFile + "temp.txt"

	file1, err := os.Open(srcFile)
	handelError(err)
	file2, err := os.OpenFile(distFile, os.O_CREATE|os.O_WRONLY, os.ModePerm)
	handelError(err)
	file3, err := os.OpenFile(tempFile, os.O_CREATE|os.O_RDWR, os.ModePerm) //可读可写
	handelError(err)

	defer file1.Close()
	defer file2.Close()
	defer file3.Close()

	//先读取临时文件中的数据,再seek
	file3.Seek(0, io.SeekStart)
	bs := make([]byte, 100, 100)
	n1, err := file3.Read(bs)
	//handelError(err)
	countStr := string(bs[:n1])
	count, err := strconv.ParseInt(countStr, 10, 64)
	//handelError(err)
	//fmt.Println(count)

	//设置读,写的位置
	file1.Seek(count, io.SeekStart)
	file2.Seek(count, io.SeekStart)
	data := make([]byte, 1024, 1024)
	n2 := -1            //读取的数据量
	n3 := -1            //写出的数据量
	total := int(count) //读取的总量

	//复制文件
	for {
		n2, err = file1.Read(data)
		if err == io.EOF || n2 == 0 {
			fmt.Println("文件复制完毕:", total)
			file3.Close()
			//一旦复制完,就删除临时文件
			os.Remove(tempFile)
			break
		}
		n3, err = file2.Write(data[:n2])
		total += n3

		//将赋值的总量存储到临时文件中
		file3.Seek(0, io.SeekStart)
		file3.WriteString(strconv.Itoa(total))

		fmt.Println("已经复制了", total, "字节数据")
		//模拟断电
		if total > 5000 {
			panic("断电啦")
		}
	}
}

func handelError(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

第一次传输的时候,在其中模拟断电(panic),如下图所示,文件复制到  5120  字节时断电。后恢复,文件接着从5123字节开始复制,而不会从头开始复制~~

golang之文件读写/复制/断点续传_第12张图片

(3)遍历文件夹

golang之文件读写/复制/断点续传_第13张图片

你可能感兴趣的:(golang)