-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpart.go
More file actions
84 lines (69 loc) · 1.55 KB
/
part.go
File metadata and controls
84 lines (69 loc) · 1.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package smartremote
import (
"bufio"
"encoding/binary"
"os"
)
// SavePart triggers an immediate save of the download status to a .part file
// on disk, allowing resume to happen if the program terminates and is opened
// again.
func (f *File) SavePart() error {
f.lk.Lock()
defer f.lk.Unlock()
return f.savePart()
}
// savePart writes the current download status to a .part file. If the file
// is complete, the .part file is removed instead. Uses atomic rename for safety.
func (f *File) savePart() error {
// save partial file
if f.complete {
// remove part file if any
os.Remove(f.path + ".part")
os.Remove(f.path + ".wpart")
return nil
}
out, err := os.Create(f.path + ".wpart")
if err != nil {
return err
}
// write block size
buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutVarint(buf, f.blkSize)
_, err = out.Write(buf[:n])
if err != nil {
out.Close()
os.Remove(f.path + ".wpart")
return err
}
// write bitmap
_, err = f.status.WriteTo(out)
out.Close()
if err != nil {
os.Remove(f.path + ".wpart")
return err
}
return os.Rename(f.path+".wpart", f.path+".part")
}
// readPart loads download status from a .part file to resume a previous download.
func (f *File) readPart() error {
in, err := os.Open(f.path + ".part")
if err != nil {
return err
}
buf := bufio.NewReader(in)
// read blksize
t, err := binary.ReadVarint(buf)
if err != nil {
in.Close()
return err
}
// read map
_, err = f.status.ReadFrom(buf)
in.Close()
if err != nil {
f.status.Clear()
return err
}
f.blkSize = t
return nil
}