VB.NET FTP下载文件损坏

时间:2014-03-19 06:58:02

标签: vb.net ftp

我想下载位于FTP站点上的所有文件。我打破了2个操作。首先是获取目录中所有文件的列表。然后我继续下载每个文件的第二个。但不幸的是,下载的文件已损坏。最糟糕的是,它会影响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

1 个答案:

答案 0 :(得分: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)