2014-03-25 49 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的作者)