Skip to content

SFTP Examples

Andrew Lambert edited this page Nov 6, 2020 · 17 revisions

SSH File Transfer Protocol

SFTP is a protocol for managing files on a server over SSH.

Download

This example downloads a file over SFTP. For extended features like reading file metadata refer to the SFTPStream class:

  Dim session As SSH.Session = SSH.Connect("ssh://user:[email protected]/")
  Dim sftp As New SSH.SFTPSession(session)
  Dim reader As SSHStream = sftp.Get("file.txt")
  Dim writer As BinaryStream = BinaryStream.Create(SpecialFolder.Desktop.Child("file.txt"))
  
  Do Until reader.EOF
    writer.Write(reader.Read(1024))
  Loop
  
  reader.Close
  writer.Close

Upload

This example uploads a file over SFTP. For extended features like appending to an existing file refer to the SFTPStream class:

  Dim session As SSH.Session = SSH.Connect("ssh://user:[email protected]/")
  Dim sftp As New SSH.SFTPSession(session)
  Dim writer As SSHStream = sftp.Put("file.txt")
  Dim reader As BinaryStream = BinaryStream.Open(SpecialFolder.Desktop.Child("file.txt"))
  
  Do Until reader.EOF
    writer.Write(reader.Read(1024))
  Loop
  
  reader.Close
  writer.Close

List directory

This example uses the SFTPDirectory class to get the names of files/subdirectories in a remote directory using SFTP:

  Dim session As SSH.Session = SSH.Connect("ssh://user:[email protected]/")
  Dim sftp As New SSH.SFTPSession(session)
  Dim names() As String
  Dim lister As SSH.SFTPDirectory = sftp.ListDirectory("/path/to/dir/")
  
  Do
    names.Append(lister.CurrentName)
  Loop Until Not lister.ReadNextEntry()

  lister.Close

Recursive download

This example uses the SFTPTransferQueue class to manage simultaneous downloads while recursively downloading a remote directory tree.

Sub DownloadDirectory(Session As SSH.SFTPSession, Queue As SSH.SFTPTransferQueue, DirectoryPath As String, LocalDirectory As FolderItem, Optional RelativeRoot As String)
  ' normalize the DirectoryPath
  If Right(DirectoryPath, 1) <> "/" Then DirectoryPath = DirectoryPath + "/"
  If RelativeRoot = "" Then RelativeRoot = DirectoryPath
  Dim relativepath As String = Replace(DirectoryPath, RelativeRoot, "")
  
  ' locate or create the corresponding local directory
  Dim thisdir As FolderItem = LocalDirectory
  Dim path() As String = relativepath.Split("/")
  For i As Integer = 0 To UBound(path)
    If path(i).Trim = "" Then Continue
    thisdir = thisdir.Child(path(i))
    If thisdir.Directory Then Continue
    If thisdir.Exists Then Raise New IOException ' file exists with the name of a directory we need
    thisdir.CreateAsFolder()
  Next
  
  Dim startcount As Integer = Queue.Count
  ' begin listing the contents of DirectoryPath
  Dim lister As SSH.SFTPDirectory = Session.ListDirectory(DirectoryPath)
  Do
    Select Case lister.CurrentType
    Case SSH.SFTPEntryType.Unknown
      ' skip. Either a weird custom type or the directory is empty
      Continue
      
    Case SSH.SFTPEntryType.Directory
      ' recurse into the subdirectory
      DownloadDirectory(Session, Queue, DirectoryPath + lister.CurrentName, LocalDirectory, RelativeRoot)
      
    Else
      ' prepare the download
      Dim download As SSH.SFTPStream = lister.OpenFile()
      Dim file As FolderItem = thisdir.Child(lister.CurrentName)
      Dim output As BinaryStream = BinaryStream.Create(file)
      
      ' run the queue for a bit if needed
      Do Until Queue.Count < Queue.MaxCount
        If Not Queue.PerformOnce() Then Exit Do
      Loop
      
      ' add the download to the queue
      Queue.AddDownload(download, output)

    End Select
    
  Loop Until Not lister.ReadNextEntry()
  lister.Close
  
  ' run the queue until there are fewer downloads remaining than we started with
  Do Until Queue.Count <= startcount
    If Not Queue.PerformOnce() Then Exit Do
  Loop
End Sub

Usage example:

  Dim session As SSH.Session = SSH.Connect("ssh://user:[email protected]/")
  Dim sftp As New SSH.SFTPSession(session)
  Dim queue As New SSH.SFTPTransferQueue
  Dim localroot As FolderItem = SelectFolder()
  DownloadDirectory(sftp, queue, "/home/username/example/", localroot)

Recursive upload

This example uses the SFTPTransferQueue class to manage simultaneous uploads while recursively uploading a local directory tree.

Sub UploadDirectory(Session As SSH.SFTPSession, Queue As SSH.SFTPTransferQueue, DirectoryPath As String, LocalDirectory As FolderItem)
  ' Normalize the DirectoryPath and create the remote directory if needed
  If Right(DirectoryPath, 1) <> "/" Then DirectoryPath = DirectoryPath + "/"
  If Not Session.PathExists(DirectoryPath) Then
    Session.MakeDirectory(DirectoryPath)
  End If
  
  Dim startcount As Integer = Queue.Count
  
  ' begin listing the contents of LocalDirectory
  Dim c As Integer = LocalDirectory.Count
  For i As Integer = 1 To c
    Dim item As FolderItem = LocalDirectory.Item(i)
    If item.Directory Then
      ' recurse into the subdirectory
      UploadDirectory(Session, Queue, DirectoryPath + item.Name, item)
      
    Else
      ' prepare the upload
      Dim reader As BinaryStream = BinaryStream.Open(item)
      Dim writer As SSH.SFTPStream = Session.Put(DirectoryPath + item.Name)
      
      ' run the queue for a bit if needed
      Do Until Queue.Count < Queue.MaxCount
        If Not Queue.PerformOnce() Then Exit Do
      Loop
      
      ' add the upload to the queue
      Queue.AddUpload(writer, reader)

    End If
  Next
  
  ' run the queue until there are fewer uploads remaining than we started with
  Do Until Queue.Count <= startcount
    If Not Queue.PerformOnce() Then Exit Do
  Loop
End Sub

Usage example:

  Dim session As SSH.Session = SSH.Connect("ssh://user:[email protected]/")
  Dim sftp As New SSH.SFTPSession(session)
  Dim queue As New SSH.SFTPTransferQueue
  Dim localroot As FolderItem = SelectFolder()
  UploadDirectory(sftp, queue, "/home/user/Desktop/example/", localroot)
Clone this wiki locally