如題:
註釋在代碼中
package main
import (
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
)
func main() {
//C:\Users\Administrator\go\src\breakpoint\point.jpg
//C:/Users/Administrator/Desktop/test.jpg
//srcFile := "C:/Users/Administrator/go/src/breakpoint/point.jpg"
//C:/Users/Administrator/Desktop/test.jpg
// 需要複製的源文件
srcFile := "C:/Users/Administrator/Desktop/test.jpg"
// 複製到的目標文件
destFile := srcFile[strings.LastIndex(srcFile, "/")+1:] //point.jpg
fmt.Println(destFile)
// 臨時文件
tmpFiel := destFile + "temp.txt"
fmt.Println(tmpFiel)
// 打開源文件,只讀用Open()
file1, err := os.Open(srcFile)
HandleErr(err)
// 打開/創建目標文件,操作目標文件對象
file2, err := os.OpenFile(destFile, os.O_CREATE|os.O_WRONLY, os.ModePerm)
HandleErr(err)
// 打開/創建臨時文件,操作臨時文件對象
file3, err := os.OpenFile(tmpFiel, os.O_CREATE|os.O_RDWR, os.ModePerm)
HandleErr(err)
defer file1.Close()
defer file2.Close()
//#1.先讀取臨時文件裏面的數據,再seek()
file3.Seek(0, io.SeekStart)
// 讀取的自己數組
bs := make([]byte, 100, 100)
// 臨時文件讀取
n1, err := file3.Read(bs)
//HandleErr(err)
countStr := string(bs[:n1])
// 臨時文件中記錄讀取的數量/字節數
count, err := strconv.ParseInt(countStr, 10, 64)
//HandleErr(err)
fmt.Println(count)
// #2.設置偏移量,讀寫位置
file1.Seek(count, io.SeekStart)
file2.Seek(count, io.SeekStart)
//讀取文件數據量1024個字節
data := make([]byte, 1024, 1024)
n2 := -1 //讀取的數據量
n3 := -1 //寫出的數據量
total := int(count) //讀取的總量
// #3.複製文件
for {
// 讀取源文件,每次讀1024個字節
n2, err = file1.Read(data)
if err == io.EOF || n2 == 0 {
fmt.Println("文件複製完畢...", total)
file3.Close()
os.Remove(tmpFiel)
break
}
// 寫入目標文件
n3, err = file2.Write(data[:n2])
// 讀取總量相加
total += n3
// 將複製的總量,存儲在臨時文件中,從頭開始寫
file3.Seek(0, io.SeekStart)
// 寫入臨時文件中讀取的數據量的位置
file3.WriteString(strconv.Itoa(total))
fmt.Printf("total: %d\n", total)
//模擬斷點,第一次放開註釋,使程序中斷,第二次,完成續傳,文件傳遞完畢後刪除臨時文件
//if total > 8000 {
// panic("假裝斷電")
//}
}
}
func HandleErr(err error) {
if err != nil {
log.Fatal(err)
}
}
實現思路:
讀取的字節數量,存放在一個臨時文件中,當程序被中斷,再次讀取的時候,去臨時文件中將那個數據拿到,從臨時文件中存儲的數據再次開始讀取文件,讀取完畢後,刪除臨時文件.
臨時文件只是記錄讀取的位置