2014-03-25 51 views
4

我試圖從FTP服務器上多個目錄下載到我的本地機器,如何從FTP使用VB.NET

我已經試過了,

Const localFile As String = "C:\Documents and Settings\cr\Desktop\T\New Folder\" 
Const remoteFile As String = "textbox.Text" 
Const host As String = "ftp://ftp.example.com" 
Const username As String = "username" 
Const password As String = "password" 

For i1 = 0 To ListBox1.SelectedItems.Count - 1 
    Dim li As New ListViewItem 
    li = ListView1.Items.Add(ListBox1.SelectedItems(i1)) 
    Dim URI1 As String = host + remoteFile & "/" & ListBox1.SelectedItems(i1) 
    Dim ftp1 As System.Net.FtpWebRequest = CType(FtpWebRequest.Create(URI1), FtpWebRequest) 
    ftp1.Credentials = New System.Net.NetworkCredential(username, password) 
    ftp1.KeepAlive = False 
    ftp1.UseBinary = True 
    ftp1.Method = System.Net.WebRequestMethods.Ftp.DownloadFile 
    Using response As System.Net.FtpWebResponse = CType(ftp1.GetResponse, System.Net.FtpWebResponse) 
     Using responseStream As IO.Stream = response.GetResponseStream 

      Dim length As Integer = response.ContentLength 
      Dim bytes(length) As Byte 

      'loop to read & write to file 
      Using fs As New IO.FileStream(localFile & ListBox1.SelectedItems(i1), IO.FileMode.Create) 
       Dim buffer(2047) As Byte 
       Dim read As Integer = 1 

       Do 
        read = responseStream.Read(buffer, 0, buffer.Length) 
        fs.Write(buffer, 0, read) 

       Loop Until read = 0 'see Note(1) 
       responseStream.Close() 
       fs.Flush() 
       fs.Close() 
      End Using 
      responseStream.Close() 
     End Using 

     response.Close() 
    End Using 
    li.BackColor = Color.Aquamarine 
Next 

但這裏的問題是,下載目錄我可以從文件夾下載多個文件,但無法從主目錄下載子目錄及其內容。

基本上主目錄都由文件和子目錄組成。那麼有什麼方法可以從FTP下載子目錄及其內容?

在此先感謝。

+0

你必須遞歸到子文件夾。所以:下載文件>輸入子文件夾>重複 – WozzeC

+0

@WozzeC可以給我提供一些提示或鏈接,對於相同的提示或鏈接 –

回答

-1

看看我的FTP類:它非常簡單。

看看我的FTP類,它可能正是你需要的。

Public Class FTP 
     '-------------------------[BroCode]-------------------------- 
     '----------------------------FTP----------------------------- 
     Private _credentials As System.Net.NetworkCredential 
     Sub New(ByVal _FTPUser As String, ByVal _FTPPass As String) 
      setCredentials(_FTPUser, _FTPPass) 
     End Sub 
     Public Sub UploadFile(ByVal _FileName As String, ByVal _UploadPath As String) 
      Dim _FileInfo As New System.IO.FileInfo(_FileName) 
      Dim _FtpWebRequest As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(New Uri(_UploadPath)), System.Net.FtpWebRequest) 
      _FtpWebRequest.Credentials = _credentials 
      _FtpWebRequest.KeepAlive = False 
      _FtpWebRequest.Timeout = 20000 
      _FtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile 
      _FtpWebRequest.UseBinary = True 
      _FtpWebRequest.ContentLength = _FileInfo.Length 
      Dim buffLength As Integer = 2048 
      Dim buff(buffLength - 1) As Byte 
      Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead() 
      Try 
       Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream() 
       Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength) 
       Do While contentLen <> 0 
        _Stream.Write(buff, 0, contentLen) 
        contentLen = _FileStream.Read(buff, 0, buffLength) 
       Loop 
       _Stream.Close() 
       _Stream.Dispose() 
       _FileStream.Close() 
       _FileStream.Dispose() 
      Catch ex As Exception 
       MessageBox.Show(ex.Message, "Upload Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error) 
      End Try 
     End Sub 
     Public Sub DownloadFile(ByVal _FileName As String, ByVal _ftpDownloadPath As String) 
      Try 
       Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpDownloadPath) 
       _request.KeepAlive = False 
       _request.Method = System.Net.WebRequestMethods.Ftp.DownloadFile 
       _request.Credentials = _credentials 
       Dim _response As System.Net.FtpWebResponse = _request.GetResponse() 
       Dim responseStream As System.IO.Stream = _response.GetResponseStream() 
       Dim fs As New System.IO.FileStream(_FileName, System.IO.FileMode.Create) 
       responseStream.CopyTo(fs) 
       responseStream.Close() 
       _response.Close() 
      Catch ex As Exception 
       MessageBox.Show(ex.Message, "Download Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error) 
      End Try 
     End Sub 
     Public Function GetDirectory(ByVal _ftpPath As String) As List(Of String) 
      Dim ret As New List(Of String) 
      Try 
       Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpPath) 
       _request.KeepAlive = False 
       _request.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails 
       _request.Credentials = _credentials 
       Dim _response As System.Net.FtpWebResponse = _request.GetResponse() 
       Dim responseStream As System.IO.Stream = _response.GetResponseStream() 
       Dim _reader As System.IO.StreamReader = New System.IO.StreamReader(responseStream) 
       Dim FileData As String = _reader.ReadToEnd 
       Dim Lines() As String = FileData.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) 
       For Each l As String In Lines 
        ret.Add(l) 
       Next 
       _reader.Close() 
       _response.Close() 
      Catch ex As Exception 
       MessageBox.Show(ex.Message, "Directory Fetch Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error) 
      End Try 
      Return ret 
     End Function 

     Private Sub setCredentials(ByVal _FTPUser As String, ByVal _FTPPass As String) 
      _credentials = New System.Net.NetworkCredential(_FTPUser, _FTPPass) 
     End Sub 
    End Class 

初始化:

Dim ftp As New FORM.FTP("username", "password") 

ftp.UploadFile("c:\file.jpeg", "ftp://domain/file.jpeg") 

ftp.DownloadFile("c:\file.jpeg", "ftp://ftp://domain/file.jpeg") 

Dim directory As List(Of String) = ftp.GetDirectory("ftp://ftp.domain.net/") 
     ListBox1.Items.Clear() 
     For Each item As String In directory 
      ListBox1.Items.Add(item) 
     Next 
1

翻譯我的回答C# Download all files and subdirectories through FTP到VB.NET:

FtpWebRequest沒有遞歸文件下載(或任何明確支持任何其他遞歸操作)。你必須執行遞歸自己:

  • 列出遠程目錄
  • 迭代項,下載文件,並在遞歸到子目錄(再次列出這些,等)

一個棘手的部分是從子目錄中識別文件。 FtpWebRequest無法通過便攜式方式執行此操作。 FtpWebRequest不幸地不支持MLSD命令,這是在FTP協議中使用文件屬性檢索目錄列表的唯一便攜方式。另請參閱Checking if object on FTP server is file or directory

的選項有:

  • 請在是肯定要失敗的文件,併成功爲目錄(反之亦然)的文件名操作。即你可以嘗試下載「名稱」。如果成功,它就是一個文件,如果失敗了,它就是一個目錄。
  • 你可能是幸運的,在特定情況下,可以通過文件名告訴從目錄中的文件(即所有文件的擴展名,而子目錄不)
  • 您使用長的目錄列表(LIST命令= ListDirectoryDetails方法)並嘗試解析服務器特定的列表。許多FTP服務器使用* nix風格的列表,其中您在條目的最開始處用d標識了一個目錄。但是許多服務器使用不同的格式。下面的示例使用這種方法(假設* nix的格式)
Sub DownloadFtpDirectory(
     url As String, credentials As NetworkCredential, localPath As String) 
    Dim listRequest As FtpWebRequest = WebRequest.Create(url) 
    listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails 
    listRequest.Credentials = credentials 

    Dim lines As List(Of String) = New List(Of String) 

    Using listResponse As FtpWebResponse = listRequest.GetResponse(), 
      listStream As Stream = listResponse.GetResponseStream(), 
      listReader As StreamReader = New StreamReader(listStream) 
     While Not listReader.EndOfStream 
      lines.Add(listReader.ReadLine()) 
     End While 
    End Using 

    For Each line As String In lines 
     Dim tokens As String() = 
      line.Split(New Char() {" "}, 9, StringSplitOptions.RemoveEmptyEntries) 
     Dim name As String = tokens(8) 
     Dim permissions As String = tokens(0) 

     Dim localFilePath As String = Path.Combine(localPath, name) 
     Dim fileUrl As String = url + name 

     If permissions(0) = "d" Then 
      If Not Directory.Exists(localFilePath) Then 
       Directory.CreateDirectory(localFilePath) 
      End If 
      DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath) 
     Else 
      Dim downloadRequest As FtpWebRequest = WebRequest.Create(fileUrl) 
      downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile 
      downloadRequest.Credentials = credentials 

      Using downloadResponse As FtpWebResponse = downloadRequest.GetResponse(), 
        sourceStream As Stream = downloadResponse.GetResponseStream(), 
        targetStream As Stream = File.Create(localFilePath) 
       Dim buffer As Byte() = New Byte(10240 - 1) {} 
       Dim read As Integer 
       Do 
        read = sourceStream.Read(buffer, 0, buffer.Length) 
        If read > 0 Then 
         targetStream.Write(buffer, 0, read) 
        End If 
       Loop While read > 0 
      End Using 
     End If 
    Next 
End Sub 

使用功能,如:

Dim credentials As NetworkCredential = New NetworkCredential("user", "mypassword") 
Dim url As String = "ftp://ftp.example.com/directory/to/download/" 
DownloadFtpDirectory(url, credentials, "C:\target\directory") 

如果你想避免與解析服務器 - 煩惱特定的目錄列表格式,請使用支持MLSD命令和/或解析各種LIST列表格式的第三方庫;和遞歸下載。

例如與WinSCP .NET assembly您可以到Session.GetFiles單個呼叫下載整個目錄:

' Setup session options 
Dim SessionOptions As SessionOptions = New SessionOptions 
With SessionOptions 
    .Protocol = Protocol.Ftp 
    .HostName = "ftp.example.com" 
    .UserName = "user" 
    .Password = "mypassword" 
End With 

Using session As Session = New Session() 
    ' Connect 
    session.Open(SessionOptions) 

    ' Download files 
    session.GetFiles("/directory/to/download/*", "C:\target\directory\*").Check() 
End Using 

內部,WinSCP賦予使用MLSD命令,如果服務器支持。如果不是,則使用LIST命令並支持數十種不同的列表格式。

默認情況下,Session.GetFiles method是遞歸的。

(我的WinSCP的作者)