2014-03-19 123 views
0

我想下载FTP站点上的所有文件。我闯入2个操作。首先是获取目录中所有文件的列表。然后我继续下载每个文件。但不幸的是,下载的文件已损坏。最糟糕的是,它会影响FTP文件夹上的文件。两个文件夹都包含损坏的文件。从查看缩略图图像到默认图像缩略图。这是怎么发生的并克服这个问题?以下是我的代码;完整的代码类。我作为提供参考和指导做了正确的方式:)VB.NET FTP下载文件损坏

Private strTargetPath As String 
Private strDestPath As String 

Private Sub frmLoader_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    Try 
     objSQL = New clsSQL 
     If objSQL.SQLGetAllData Then 'Get data from SQL and insert into an arraylist 
      strTargetPath = "ftp://192.168.1.120/image/" 
      strDestPath = "D:\Application\FTPImg\" 
      ListFileFromFTP() 
     End If 
    Catch ex As Exception 
     strErrMsg = "Oops! Something is wrong with loading login form." 
     MessageBox.Show(strErrMsg & vbCrLf & "ExMsg: " & ex.Message, "Error message!", MessageBoxButtons.OK, MessageBoxIcon.Error) 
    End Try 
End Sub 
Private Sub ListFileFromFTP() 
    Dim arrFile As ArrayList 
    Dim strPath As String 
    Try 
     Dim reqFTP As FtpWebRequest 
     reqFTP = FtpWebRequest.Create(New Uri(strTargetPath)) 
     reqFTP.UseBinary = True 
     reqFTP.Credentials = New NetworkCredential("user", "user123") 
     reqFTP.Method = WebRequestMethods.Ftp.ListDirectory 
     reqFTP.Proxy = Nothing 
     reqFTP.KeepAlive = False 
     reqFTP.UsePassive = False 
     Dim response As FtpWebResponse = DirectCast(reqFTP.GetResponse(), FtpWebResponse) 
     Dim sr As StreamReader 
     sr = New StreamReader(reqFTP.GetResponse().GetResponseStream()) 
     Dim FileListing As String = sr.ReadLine 
     arrFile = New ArrayList 
     While FileListing <> Nothing 
      strPath = strTargetPath & FileListing 
      arrFile.Add(strPath) 
      FileListing = sr.ReadLine 
     End While 
     sr.Close() 
     sr = Nothing 
     reqFTP = Nothing 
     response.Close() 
     For i = 0 To (arrFile.Count - 1) 
      DownloadImage(arrFile.Item(i)) 
     Next 
    Catch ex As Exception 
     strErrMsg = "Oops! Something is wrong with ListFileFromFTP." 
     MessageBox.Show(strErrMsg & vbCrLf & "ExMsg: " & ex.Message, "Error message!", MessageBoxButtons.OK, MessageBoxIcon.Error) 
    End Try 
End Sub 
Public Function DownloadImage(ByVal strName As String) As String 
    Dim ftp_request As FtpWebRequest = Nothing 
    Dim ftpStream As Stream = Nothing 

    Dim strOldName As String 
    Dim strNewName As String 
    Dim withoutextension As String 
    Dim extension As String 
    Try 
     strOldName = strTargetPath & strName 
     withoutextension = Path.GetFileNameWithoutExtension(strOldName) 
     extension = Path.GetExtension(strOldName) 
     strNewName = strDestPath & withoutextension & extension 

     ftp_request = CType(System.Net.FtpWebRequest.Create(strName), System.Net.FtpWebRequest) 
     ftp_request.Method = System.Net.WebRequestMethods.Ftp.UploadFile 
     ftp_request.Credentials = New System.Net.NetworkCredential("user", "user123") 
     ftp_request.UseBinary = True 
     ftp_request.KeepAlive = False 
     ftp_request.Proxy = Nothing 
     Dim response As FtpWebResponse = DirectCast(ftp_request.GetResponse(), FtpWebResponse) 
     Dim responseStream As IO.Stream = response.GetResponseStream 

     Dim fs As New IO.FileStream(strNewName, IO.FileMode.Create) 
     Dim buffer(2047) As Byte 
     Dim read As Integer = 0 
     Do 
      read = responseStream.Read(buffer, 0, buffer.Length) 
      fs.Write(buffer, 0, read) 
     Loop Until read = 0 
     responseStream.Close() 
     fs.Flush() 
     fs.Close() 
     responseStream.Close() 
     response.Close() 
    Catch ex As WebException 
     Dim response As FtpWebResponse = ex.Response 
     If response.StatusCode = FtpStatusCode.ActionNotTakenFileUnavailable Then 
      MsgBox(response.StatusDescription) 
      Return String.Empty 
     Else 
      MsgBox(response.StatusDescription) 
     End If 
    End Try 
End Function 

对于下载文件,这是取得成功的正确代码:

Private Sub Download(ByVal strFTPPath As String) 
     Dim reqFTP As FtpWebRequest = Nothing 
     Dim ftpStream As Stream = Nothing 
     Try 
      Dim outputStream As New FileStream(strDestPath & strImgName, FileMode.Create) 
      reqFTP = DirectCast(FtpWebRequest.Create(New Uri(strFTPPath)), FtpWebRequest) 
      reqFTP.Method = WebRequestMethods.Ftp.DownloadFile 
      reqFTP.UseBinary = True 
      reqFTP.Credentials = New NetworkCredential("user", "user123") 
      Dim response As FtpWebResponse = DirectCast(reqFTP.GetResponse(), FtpWebResponse) 
      ftpStream = response.GetResponseStream() 
      Dim cl As Long = response.ContentLength 
      Dim bufferSize As Integer = 2048 
      Dim readCount As Integer 
      Dim buffer As Byte() = New Byte(bufferSize - 1) {} 

      readCount = ftpStream.Read(buffer, 0, bufferSize) 
      While readCount > 0 
       outputStream.Write(buffer, 0, readCount) 
       readCount = ftpStream.Read(buffer, 0, bufferSize) 
      End While 
      ftpStream.Close() 
      outputStream.Close() 
      response.Close() 
     Catch ex As Exception 
      If ftpStream IsNot Nothing Then 
       ftpStream.Close() 
       ftpStream.Dispose() 
      End If 
      Throw New Exception(ex.Message.ToString()) 
     End Try 
    End Sub 

回答

0

有一些奇怪的事情在你的代码。您正在关闭responseStream两次。

而你正在使用ftp请求方法uploadFile。但随后下载它。

而不是使用ftp的东西使用这个来代替。它更简单,你将缓冲区和数据流外包给微软,这应该比我们少一些。

Dim webClient = new WebClient() 
webClient.Credentials = new NetworkCredential("user", "user123") 
dim response = webClient.UploadFile("ftp://MyFtpAddress","c:\myfile.jpg") 
dim sResponse = System.Text.Encoding.Default.GetString(response) 
+0

Oh..sorry.my不好。我只是修复下载的代码。我会测试新的下载代码。顺便说一下,是下载每个文件的方式吗?看起来很简单。好吗? – Luiey

+0

我的真实下载代码:这是工作: – Luiey

+0

是的,这是今天的方式。没有流:)。经常损坏的文件是因为您需要刷新然后关闭。而人们经常忘记或错误的错误处理将保持文件打开并将流保存在内存中。 – Archlight