Базовая реализация передачи возобновления точки останова файла

Go

Принцип возобновления точки останова

Каждый раз, когда вы копируете, используйте поиск, чтобы записать смещение и записать его в локальный файл.В следующий раз, когда вы копируете, читайте с записанного смещения.

В последнем коде загрузки была ошибка, которая была исправлена.

Код

  • основной метод
func ContinueCopy(srcFile, destDir string) (int, error) {
	// 1. 定义源文件
	fileSrc, err := os.Open(srcFile)
	if err != nil {
		return 0, err
	}
	log.Printf("源文件名称:%s\n", fileSrc.Name())

	// 2. 定义目标文件位置,不存在时自动创建
	destFile := destDir + srcFile[strings.LastIndex(srcFile, "/")+1:]
	fileDest, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE, os.ModePerm)
	if err != nil {
		return 0, err
	}
	log.Printf("目标文件名称:%s\n", fileDest.Name())

	// 3. 定义零时文件位置,不存在时自动创建(不建议使用ioutil.TempFile(),不便下次找到)
	tempFile := destFile + "_temp"
	fileTemp, err := os.OpenFile(tempFile, os.O_WRONLY|os.O_CREATE, os.ModePerm)
	if err != nil {
		return 0, err
	}
	log.Printf("临时文件名称:%s\n", fileTemp.Name())

	// 4. 关闭文件
	defer fileSrc.Close()
	defer fileDest.Close()
	defer fileTemp.Close()

	// 6. 读取临时文件中的偏移量的值
	tempOffsetStr, err := ioutil.ReadFile(tempFile)
	tempOffSet, err := strconv.ParseInt(string(tempOffsetStr), 10, 64)

	// 7. 本次拷贝的初始位置
	fileSrc.Seek(tempOffSet, io.SeekStart)
	fileDest.Seek(tempOffSet, io.SeekStart)
	data := make([]byte, 1024, 1024)
	countOut := -1           //	读出的总量
	countIn := -1            // 写入的总量
	total := int(tempOffSet) // 总量

	srcRead := bufio.NewReader(fileSrc)
	destWrite := bufio.NewWriter(fileDest)

	// 8. 拷贝文件
	for {
		countOut, err = srcRead.Read(data)
		if err == io.EOF || countOut == 0 {
			log.Printf("文件拷贝完成,总共: %d字节\n", total)
			fileTemp.Close()
			os.Remove(tempFile)
			return 1, nil
		}
		//destFile := bufio.NewWriter(fileDest)
		countIn, err = destWrite.Write(data[:countOut])
		destWrite.Flush()
		total += countIn

		// 9. 将当前复制的偏移量,存储到临时文件
		fileTemp.Seek(0, io.SeekStart)
		fileTemp.WriteString(strconv.Itoa(total))

		// 10. 建设异常情况,突然终止拷贝
		UnknownErr(total)
	}
}
  • Как настроить работу терминальной программы
// 2M时中断程序
func UnknownErr(n int) {
	if n == 1024*2 {
		panic("something has coursed error...")
	}
}
  • Тестовая операция
func main() {
	srcFile := "e:/temp/img02.jpg"
	destDir := "d:/pic/"

	_, err := ContinueCopy(srcFile, destDir)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("拷贝完成")
}

текущий результат

  • Первый запуск, столкнулся с прерыванием

  • Продолжайте работать во второй раз

Скопируйте файл во второй раз, автоматически начните копирование с позиции 2048 и автоматически удалите его после завершения.

Примечание. Если содержимое файла невелико, например меньше буфера, вы можете использовать его напрямую.io.Copy()Просто