Add resume support to downloads
This commit is contained in:
parent
4a95d40623
commit
101a3ff39c
1 changed files with 32 additions and 5 deletions
37
easysftp.go
37
easysftp.go
|
@ -99,8 +99,8 @@ func (c *Client) Lstat(path string) (os.FileInfo, error) {
|
||||||
return sftpClient.Lstat(path)
|
return sftpClient.Lstat(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download a file from the given path to the output writer
|
// Download a file from the given path to the output writer with the given offset of the remote file
|
||||||
func (c *Client) Download(path string, output io.Writer) error {
|
func (c *Client) Download(path string, output io.Writer, offset int64) error {
|
||||||
sftpClient, err := c.newSftpClient()
|
sftpClient, err := c.newSftpClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -124,12 +124,18 @@ func (c *Client) Download(path string, output io.Writer) error {
|
||||||
|
|
||||||
defer remote.Close()
|
defer remote.Close()
|
||||||
|
|
||||||
|
_, err = remote.Seek(offset, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_, err = io.Copy(output, remote)
|
_, err = io.Copy(output, remote)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mirror downloads an entire folder (recursively) or file underneath the given localParentPath
|
// Mirror downloads an entire folder (recursively) or file underneath the given localParentPath
|
||||||
func (c *Client) Mirror(path string, localParentPath string) error {
|
// resume will continue downloading interrupted files
|
||||||
|
func (c *Client) Mirror(path string, localParentPath string, resume bool) error {
|
||||||
sftpClient, err := c.newSftpClient()
|
sftpClient, err := c.newSftpClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -154,9 +160,19 @@ func (c *Client) Mirror(path string, localParentPath string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flags := os.O_RDWR | os.O_CREATE
|
||||||
|
|
||||||
|
if resume {
|
||||||
|
// append to the end of the file
|
||||||
|
flags |= os.O_APPEND
|
||||||
|
} else {
|
||||||
|
// truncate the file
|
||||||
|
flags |= os.O_TRUNC
|
||||||
|
}
|
||||||
|
|
||||||
file, err := os.OpenFile(
|
file, err := os.OpenFile(
|
||||||
localPath,
|
localPath,
|
||||||
os.O_RDWR|os.O_CREATE|os.O_TRUNC,
|
flags,
|
||||||
c.config.FileMode,
|
c.config.FileMode,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -165,7 +181,18 @@ func (c *Client) Mirror(path string, localParentPath string) error {
|
||||||
|
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
return c.Download(path, file)
|
var offset int64
|
||||||
|
if resume {
|
||||||
|
info, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// we assume that the size of the file is the resume point
|
||||||
|
offset = info.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Download(path, file, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// download the whole directory recursively
|
// download the whole directory recursively
|
||||||
|
|
Loading…
Reference in a new issue