Add resume support to downloads

This commit is contained in:
Tony Blyler 2016-05-14 11:24:44 -04:00
parent 4a95d40623
commit 101a3ff39c
No known key found for this signature in database
GPG key ID: 25C9D3A655D1A65C

View file

@ -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