Принцип возобновления точки останова
Каждый раз, когда вы копируете, используйте поиск, чтобы записать смещение и записать его в локальный файл.В следующий раз, когда вы копируете, читайте с записанного смещения.
В последнем коде загрузки была ошибка, которая была исправлена.
Код
- основной метод
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()
Просто