繁体   English   中英

VB.NET FTP下载的文件损坏

[英]VB.NET FTP Downloaded file corrupt

我想下载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

您的代码中有些奇怪的东西。 您将两次关闭responseStream。

并且您正在使用ftp请求方法uploadFile。 但是然后下载它。

而不是使用ftp的东西,而是使用它。 它要简单得多,您可以将缓冲区和流外包给microsoft,这应该比我们少一些bug。

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM