-
Notifications
You must be signed in to change notification settings - Fork 28
/
file.go
72 lines (61 loc) · 1.38 KB
/
file.go
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
package buffer
import (
"bytes"
"encoding/gob"
"fmt"
"io"
"os"
"path/filepath"
"github.com/djherbis/buffer/wrapio"
)
// File is used as the backing resource for a the NewFile BufferAt.
type File interface {
Name() string
Stat() (fi os.FileInfo, err error)
io.ReaderAt
io.WriterAt
Close() error
}
type fileBuffer struct {
file File
*wrapio.Wrapper
}
// NewFile returns a new BufferAt backed by "file" with max-size N.
func NewFile(N int64, file File) BufferAt {
return &fileBuffer{
file: file,
Wrapper: wrapio.NewWrapper(file, 0, 0, N),
}
}
func init() {
gob.Register(&fileBuffer{})
}
func (buf *fileBuffer) MarshalBinary() ([]byte, error) {
fullpath, err := filepath.Abs(filepath.Dir(buf.file.Name()))
if err != nil {
return nil, err
}
base := filepath.Base(buf.file.Name())
buf.file.Close()
buffer := bytes.NewBuffer(nil)
fmt.Fprintln(buffer, filepath.Join(fullpath, base))
fmt.Fprintln(buffer, buf.Wrapper.N, buf.Wrapper.L, buf.Wrapper.O)
return buffer.Bytes(), nil
}
func (buf *fileBuffer) UnmarshalBinary(data []byte) error {
buffer := bytes.NewBuffer(data)
var filename string
var N, L, O int64
_, err := fmt.Fscanln(buffer, &filename)
if err != nil {
return err
}
file, err := os.Open(filename)
if err != nil {
return err
}
buf.file = file
_, err = fmt.Fscanln(buffer, &N, &L, &O)
buf.Wrapper = wrapio.NewWrapper(file, L, O, N)
return err
}