|
@@ -2,6 +2,7 @@ package main
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "io"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
"regexp"
|
|
@@ -111,7 +112,7 @@ func sync(frompath, topath string) (err error) {
|
|
|
return true
|
|
|
}
|
|
|
fmt.Println(fromfile, " ==> ", tofile)
|
|
|
- frombs, e := os.ReadFile(fromfile)
|
|
|
+ frombs, e := ReadFile(fromfile)
|
|
|
if e != nil {
|
|
|
err = fmt.Errorf("from file %v", e)
|
|
|
return false
|
|
@@ -141,3 +142,54 @@ func sync(frompath, topath string) (err error) {
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+func ReadFile(name string) (data []byte, err error) {
|
|
|
+ data = make([]byte, 0, 512)
|
|
|
+ for {
|
|
|
+ data, err = ReadFileContinue(name, data)
|
|
|
+ if err == io.EOF {
|
|
|
+ err = nil
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func ReadFileContinue(name string, data []byte) ([]byte, error) {
|
|
|
+ f, err := os.Open(name)
|
|
|
+ if err != nil {
|
|
|
+ return data, err
|
|
|
+ }
|
|
|
+ defer f.Close()
|
|
|
+
|
|
|
+ var size int
|
|
|
+ if info, err := f.Stat(); err == nil {
|
|
|
+ size64 := info.Size()
|
|
|
+ if int64(int(size64)) == size64 {
|
|
|
+ size = int(size64)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ size++ // one byte for final read at EOF
|
|
|
+
|
|
|
+ // If a file claims a small size, read at least 512 bytes.
|
|
|
+ // In particular, files in Linux's /proc claim size 0 but
|
|
|
+ // then do not work right if read in small pieces,
|
|
|
+ // so an initial read of 1 byte would not work correctly.
|
|
|
+ offset := len(data)
|
|
|
+ if size > cap(data) {
|
|
|
+ ndata := make([]byte, len(data), size)
|
|
|
+ copy(ndata, data)
|
|
|
+ data = ndata
|
|
|
+ }
|
|
|
+
|
|
|
+ for {
|
|
|
+ n, err := f.ReadAt(data[offset:cap(data)], int64(offset))
|
|
|
+ offset += n
|
|
|
+ if err != nil {
|
|
|
+ return data[:offset], err
|
|
|
+ }
|
|
|
+ if offset >= cap(data) {
|
|
|
+ d := append(data[:cap(data)], 0)
|
|
|
+ data = d[:offset]
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|