|
@@ -167,7 +167,7 @@ func sync(frompath, topath string) (err error) {
|
|
|
}
|
|
|
|
|
|
func ReadFile(name string) (data []byte, err error) {
|
|
|
- fmt.Print(" -.---")
|
|
|
+ fmt.Print(" -.--%")
|
|
|
defer fmt.Println()
|
|
|
data = make([]byte, 0, 512)
|
|
|
for {
|
|
@@ -186,49 +186,64 @@ func ReadFileContinue(name string, data []byte) ([]byte, error) {
|
|
|
}
|
|
|
defer f.Close()
|
|
|
|
|
|
- var size int
|
|
|
+ var filesize int64
|
|
|
+ var bufsize int
|
|
|
if info, err := f.Stat(); err == nil {
|
|
|
- size64 := info.Size()
|
|
|
- if int64(int(size64)) == size64 {
|
|
|
- size = int(size64)
|
|
|
+ filesize = info.Size()
|
|
|
+ if int64(int(filesize)) == filesize {
|
|
|
+ bufsize = int(filesize)
|
|
|
}
|
|
|
}
|
|
|
- size++ // one byte for final read at EOF
|
|
|
+ bufsize++ // 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)
|
|
|
+ offset := int64(len(data))
|
|
|
+ if bufsize > cap(data) {
|
|
|
+ ndata := make([]byte, len(data), bufsize)
|
|
|
copy(ndata, data)
|
|
|
data = ndata
|
|
|
}
|
|
|
|
|
|
- statuschan := make(chan int, 100)
|
|
|
+ statuschan := make(chan int64, 100)
|
|
|
go func() {
|
|
|
for range statuschan {
|
|
|
- s := fmt.Sprintf("%1.3f", float64(offset)/float64(size))
|
|
|
+ s := fmt.Sprintf("%.2f%%", 100*float64(offset)/float64(filesize))
|
|
|
+ bs := strings.Repeat("\b", len(s))
|
|
|
+ fmt.Printf("%s%s", bs, s)
|
|
|
+ }
|
|
|
+ if offset >= filesize {
|
|
|
+ s := fmt.Sprintf("%.2f%%", 100.)
|
|
|
bs := strings.Repeat("\b", len(s))
|
|
|
fmt.Printf("%s%s", bs, s)
|
|
|
}
|
|
|
}()
|
|
|
+ chunk := int64(1024 * 256)
|
|
|
+ t := time.Now()
|
|
|
for {
|
|
|
- to := offset + 1024*512
|
|
|
- if to > cap(data) {
|
|
|
- to = cap(data)
|
|
|
+ to := offset + chunk
|
|
|
+ if to > int64(cap(data)) {
|
|
|
+ to = int64(cap(data))
|
|
|
}
|
|
|
n, err := f.ReadAt(data[offset:to], int64(offset))
|
|
|
- offset += n
|
|
|
+ offset += int64(n)
|
|
|
statuschan <- offset
|
|
|
if err != nil {
|
|
|
close(statuschan)
|
|
|
return data[:offset], err
|
|
|
}
|
|
|
- if offset >= cap(data) {
|
|
|
+ if offset >= int64(cap(data)) {
|
|
|
d := append(data[:cap(data)], 0)
|
|
|
data = d[:offset]
|
|
|
}
|
|
|
+ ut := time.Since(t)
|
|
|
+ if ut < 500*time.Millisecond {
|
|
|
+ chunk *= 2
|
|
|
+ } else if chunk > 1024 && ut > 5*time.Second {
|
|
|
+ chunk /= 2
|
|
|
+ }
|
|
|
+ t = time.Now()
|
|
|
}
|
|
|
}
|