78 lines
1.4 KiB
Go
78 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/mitchellh/ioprogress"
|
|
)
|
|
|
|
var (
|
|
ErrUnsupportedFile = errors.New("unsupported file")
|
|
ErrThisIsDirectory = errors.New("this is directory")
|
|
ErrOffsetExceedsFileSize = errors.New("offset exceeds file size")
|
|
ErrNoInFile = errors.New("не указан исходный файл или он не существует")
|
|
)
|
|
|
|
func Copy(fromPath string, toPath string, offset, limit int64) error {
|
|
fIn, err := os.Open(fromPath)
|
|
defer func() {
|
|
if fIn.Close() != nil {
|
|
return
|
|
}
|
|
}()
|
|
if err != nil {
|
|
return ErrNoInFile
|
|
}
|
|
|
|
fInInfo, err := fIn.Stat()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fInMode := fInInfo.Mode()
|
|
if fInMode.IsDir() {
|
|
return ErrThisIsDirectory
|
|
}
|
|
if !fInMode.IsRegular() {
|
|
return ErrUnsupportedFile
|
|
}
|
|
|
|
fInSize := fInInfo.Size()
|
|
|
|
switch {
|
|
case offset >= fInSize:
|
|
return ErrOffsetExceedsFileSize
|
|
case limit == 0:
|
|
limit = fInSize - offset
|
|
case fInSize < limit+offset:
|
|
limit = fInSize - offset
|
|
default:
|
|
}
|
|
|
|
fOut, err := os.Create(toPath)
|
|
defer func() {
|
|
if fOut.Close() != nil {
|
|
return
|
|
}
|
|
}()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pg := &ioprogress.Reader{
|
|
Reader: fIn,
|
|
Size: limit,
|
|
DrawFunc: ioprogress.DrawTerminalf(os.Stdout, ioprogress.DrawTextFormatBar(100)),
|
|
}
|
|
|
|
if _, err = fIn.Seek(offset, io.SeekStart); err != nil {
|
|
return err
|
|
}
|
|
if _, err = io.CopyN(fOut, pg, limit); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|