vb.net - FTP 下载大于 2GB 的文件 (VB.net)

标签 vb.net ftp zip unzip large-files

缺少最后几个字节并且文件被损坏 - 赏金

我现在添加了赏金来解决这个问题。我将整数类型更改为 int64,这似乎解决了部分问题,但现在当它完成下载时,有时会丢失最后 1-5 个字节,这反过来会损坏文件,因此无法解压缩。是否有另一种方法可以关闭流以确保文件完全下载并避免损坏?我已经尝试过这个简单的代码,但发生了同样的问题。

Imports System.ComponentModel
Imports System.Net

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Control.CheckForIllegalCrossThreadCalls = False
    End Sub
    Dim WithEvents WC As New WebClient
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        WC.DownloadFileAsync(New Uri("ftp://dmr-ftp-user:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aecac3dcdecfddddd9c1dccaee9b809a9a809f9d9980969a" rel="noreferrer noopener nofollow">[email protected]</a>/ESStatistikListeModtag/ESStatistikListeModtag-20160327-094743.zip"), "C:\XML\ESStatistikListeModtag-20160327-094743.zip.zip")
    End Sub
    Private Sub WC_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs) Handles WC.DownloadProgressChanged
        ProgressBar1.Value = e.ProgressPercentage
        If e.ProgressPercentage = 100 Then
            MsgBox("File download - 100%") 'This message box does trigger once the download is complete, but file is still corrupted.
        End If
    End Sub

    Private Sub WC_DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs) Handles WC.DownloadFileCompleted
        MsgBox("Complete") ' This message box doesn't trigger!
    End Sub
End Class

老问题:

我正在尝试使用 vb.net 应用程序从 FTP 服务器下载 zip 文件。我当前的源代码发布在下面。这对于较小的文件来说效果很好,但是当我超过 2GB 的限制时,我会得到以下异常:

"Arithmetic operation resulted in an overflow"

这是一个大小约为 2.5 GB 的文件,并且每个弱文件都略有增加(约 20 MB),因此我需要一个可以处理大文件的解决方案,希望没有限制。最终我也想用该程序解压缩该文件,因此如果您有任何这样做的想法,也可以发布此内容。谢谢!

 Private Sub Download(ByVal filePath As String, ByVal fileName As String)
        FTPSettings.IP = "0.0.0.0"
        FTPSettings.UserID = "ftp-user"
        FTPSettings.Password = "ftp-pass"
        Dim reqFTP As FtpWebRequest = Nothing
        Dim ftpStream As Stream = Nothing
        Try
            Dim outputStream As New FileStream(filePath + "\" + fileName, FileMode.Create)
            reqFTP = DirectCast(FtpWebRequest.Create(New Uri("ftp://" + FTPSettings.IP + "/" + fileName)), FtpWebRequest)
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile
            reqFTP.UseBinary = True
            reqFTP.Credentials = New NetworkCredential(FTPSettings.UserID, FTPSettings.Password)
            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 Int64
            Dim buffer As Byte() = New Byte(bufferSize - 1) {}
            Dim size As Int64

            readCount = ftpStream.Read(buffer, 0, bufferSize)
            While readCount > 0
                outputStream.Write(buffer, 0, readCount)
                readCount = ftpStream.Read(buffer, 0, bufferSize)

                If readCount = bufferSize Then
                    size += readCount
                    Label1.Text = size
                    Label1.Refresh()
                End If

              End While

            ftpStream.Close()
            outputStream.Close()
            response.Close()
        Catch ex As Exception
            MsgBox(ex.Message)
            If ftpStream IsNot Nothing Then
                ftpStream.Close()
                ftpStream.Dispose()
            End If
            Throw New Exception(ex.Message.ToString())
        End Try
    End Sub
    Public NotInheritable Class FTPSettings
        Private Sub New()
        End Sub
        Public Shared Property IP() As String
            Get
                Return m_IP
            End Get
            Set(ByVal value As String)
                m_IP = value
            End Set
        End Property
        Private Shared m_IP As String
        Public Shared Property UserID() As String
            Get
                Return m_UserID
            End Get
            Set(ByVal value As String)
                m_UserID = value
            End Set
        End Property
        Private Shared m_UserID As String
        Public Shared Property Password() As String
            Get
                Return m_Password
            End Get
            Set(ByVal value As String)
                m_Password = value
            End Set
        End Property
        Private Shared m_Password As String
    End Class
End Class

最佳答案

我之前在使用 WebClient 时也遇到过类似的问题,特别是与 WithEvents 语句一起使用时。 看看像这样重写代码是否可以解决问题:

Imports System.ComponentModel
Imports System.Net

Public Class Form1
    Private wc As New WebClient()

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        wc = New WebClient()

        AddHandler wc.DownloadProgressChanged, Sub(s As Object, ByVal e As DownloadProgressChangedEventArgs)
                                                Me.Invoke(New MethodInvoker(Sub() ProgressBar1.Value = e.ProgressPercentage))
                                            End Sub

        AddHandler wc.DownloadFileCompleted, Sub(s As Object, e As ComponentModel.AsyncCompletedEventArgs)
                                                MsgBox("Complete")
                                            End Sub
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        wc.DownloadFileAsync(New Uri("ftp://dmr-ftp-user:<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="87e3eaf5f7e6f4f4f0e8f5e3c7b2a9b3b3a9b6b4b0a9bfb3" rel="noreferrer noopener nofollow">[email protected]</a>/ESStatistikListeModtag/ESStatistikListeModtag-20160327-094743.zip"), "C:\XML\ESStatistikListeModtag-20160327-094743.zip.zip")
    End Sub
End Class

关于vb.net - FTP 下载大于 2GB 的文件 (VB.net),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36518334/

相关文章:

zip - 无法在 Gradle 中创建 Zip 存档

bash - 如何在没有顶级文件夹的情况下压缩文件但保留子文件夹

vb.net - VB - 如何读取和写入二进制文件?

mysql - 尝试使用 vb.net 将记录输入 mysql 数据库,但它不起作用,我不明白为什么

c# - FTP 轮询器偶尔会挂起文件下载,直到重新启动

java - 使用 Java 进行 FTP Put 命令通过 Squid HTTP 代理错误

python - 如何在 Python 中通过 cgi 部署 zip 文件(或其他二进制文件)?

c# - 将 .net Framework 项目与 .net Core 项目(和语言)混合 - System.IO.FileNotFoundException

c# - 工程转C#时ApplicationEvents.vb的函数写到哪里

ftp - 使用 ftp crate 时未解析的名称 `Binary`