Отсутствуют последние несколько байтов, и файл поврежден - щедрость
Теперь я добавил награду для решения этой проблемы. Я изменил целые типы на 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:[email protected]/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
СТАРЫЙ ВОПРОС:
Я пытаюсь загрузить zip-файл с FTP-сервера с помощью моего приложения vb.net. Мой текущий исходный код размещен ниже. Это отлично работает для небольших файлов, но когда я превышаю ограничение в 2 ГБ, я получаю следующее исключение:
"Arithmetic operation resulted in an overflow"
Это файл размером около 2,5 ГБ, который немного увеличивается с каждым слабым местом (около 20 МБ), поэтому мне нужно решение, которое может обрабатывать большие файлы, надеюсь, без ограничений. В конце концов я хотел бы также разархивировать файл с программой, поэтому, если у вас есть какие-либо идеи, как это сделать, вы также можете опубликовать это. Спасибо!
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
size += readCount
изменить размер наInt64
, а также включить Option Strict. - person Ňɏssa Pøngjǣrdenlarp   schedule 09.04.2016change size to an Int64
, вы застрянете с этим ответом и потеряете репутацию. - person Ňɏssa Pøngjǣrdenlarp   schedule 25.06.2016Control.CheckForIllegalCrossThreadCalls = False
и правильно маршалируйте любой доступ пользовательского интерфейса к потоку пользовательского интерфейса. Вы заявляете, что файл поврежден, но уверены ли вы, что используемая вами утилита ZIP может обрабатывать ZIP-файл такого размера? см.: ZIP-файл — Ограничения. - person TnTinMn   schedule 25.06.2016Console.WriteLine()
/Debug.Print
для отладки кода. MsgBox является модальным и может вызывать проблемы с асинхронным методом. - person Ňɏssa Pøngjǣrdenlarp   schedule 25.06.2016"C:\XML\ESStatistikListeModtag-20160327-094743.zip.zip"
сделано намеренно? - person A Friend   schedule 27.06.2016Try...Catch
вызывает только головную боль. Он предназначен не для блоков кода, а для отдельных строк, когда вы знаете (или, по крайней мере, подозреваете), что может пойти не так и как с этим бороться. Теперь всякий раз, когда возникает исключение, вы теряетесь. Освободите блокTry...Catch
и запустите свой код с помощью отладчика, чтобы увидеть (первую) точку отказа. - person Bozhidar Stoyneff   schedule 28.06.2016Using
предназначены для одноразовых объектов независимо от того, появляются ли они в блокахTry.Catch
. Просто объявите свои одноразовые объекты в оператореUsing
(один или несколько). Объекты, объявленные таким образом, гарантированно будут удалены в конце используемого блока, несмотря ни на что. - person Bozhidar Stoyneff   schedule 28.06.2016