Go语言实现断电续传

发布于:2024-10-17 ⋅ 阅读:(131) ⋅ 点赞:(0)

在文件传输过程中,意外的断电或网络中断可能导致传输失败,尤其是对于大型文件,从头开始重新传输既耗时又低效。

  1. 打开源文件、目标文件和一个临时文件(用于记录传输进度)。
  2. 从临时文件读取已传输的字节数。
  3. 设置源文件和目标文件的读写指针到已传输的位置。
  4. 按块复制文件内容,更新临时文件中的进度信息。
  5. 传输完成后,删除临时文件。
package main

import (
	"fmt"
	"io"
	"os"
	"strconv"
)

// 断电续传
func main() {
	//传递来的参数
	// 传输源文件地址
	srcFile := "C:\\Users\\18181\\Desktop\\client\\xiaobo.jpg"
	// 传输的目标位置
	//nowtime := time.Now()
	//timestr := nowtime.Format("2006-01-02 15:04:05")

	destFile := "D:\\OneDrive\\Godev\\src\\learngo\\lesson11time包\\server\\xiaobocopy.jpg"
	// 临时记录文件
	tempFile := "D:\\OneDrive\\Godev\\src\\learngo\\lesson11time包\\temp.txt"
	//创建对应的file对象,连接起来
	file1, err := os.Open(srcFile)
	if err != nil {
		fmt.Println("Error opening source file:", err)
		return
	}
	defer file1.Close()

	file2, err := os.OpenFile(destFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
	if err != nil {
		fmt.Println("Error opening destination file:", err)
		return
	}
	defer file2.Close()

	file3, err := os.OpenFile(tempFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
	if err != nil {
		fmt.Println("Error opening temp file:", err)
		return
	}
	//关闭文件
	defer file1.Close()
	defer file2.Close()
	fmt.Println("file1/2/3 文件连接建立完毕")
	//确认上传完毕了,关闭临时文件
	//defer file3.Close()

	// 1、读取temp.txt
	file3.Seek(0, io.SeekStart)
	buf := make([]byte, 1024, 1024)
	n, _ := file3.Read(buf)

	//2.转换为string数字
	countStr := string(buf[:n])
	count, _ := strconv.ParseInt(countStr, 10, 64)

	fmt.Println("temp.txt中记录的值为:", count) //0

	//设置读写的偏移量
	file1.Seek(count, io.SeekStart)
	file2.Seek(count, io.SeekStart)
	fmt.Println("file1/2 光标已经移动到了目标位置")

	//4开始读(复制,上传)
	bufdata := make([]byte, 1024, 1024)
	// 5、需要记录读取了多少个字节
	total := int(count)

	for {
		//6.读取数据
		readnum, err := file1.Read(bufdata)
		if err == io.EOF {
			fmt.Println("文件传输完了")
			file3.Close()
			os.Remove(tempFile)
			break
		}
		//向目标文件写入数据
		writenum, err := file2.Write(bufdata[:readnum])
		//将写入数据放到total中,在这里total就是传输进度
		total = total + writenum
		// temp.txt 存放临时记录数据
		file3.Seek(0, io.SeekStart) //将光标重置到开头
		file3.Truncate(0)           // 清空文件内容
		//file3.WriteString(strconv.FormatInt(int64(total), 10))
		file3.WriteString(strconv.Itoa(total))
		fmt.Println(total)

		//模拟断电
		//if total > 10000 {
		//	panic("断电了")
		//}
	}

}