1

有什么办法可以在我的 vb 程序中暂停文件下载?我已经尝试了 http 方法和 my.computer.net 方法,但都没有成功。我也尝试过通过这种方法暂停后台工作者:[URL] 但即使 bgworker 被暂停,下载也会继续......

Dim locationfiledownload As String
Dim whereToSave As String 'Where the program save the file

Delegate Sub ChangeTextsSafe(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
Delegate Sub DownloadCompleteSafe(ByVal cancelled As Boolean)

Public Sub DownloadComplete(ByVal cancelled As Boolean)
    ToolStripButton2.Enabled = True
    ToolStripButton3.Enabled = False

    If cancelled Then
        Me.Label4.Text = "Cancelled"
        MessageBox.Show("Download aborted", "Aborted", MessageBoxButtons.OK, MessageBoxIcon.Information)
    Else
        Me.Label4.Text = "Successfully downloaded"
        MessageBox.Show("Successfully downloaded!", "All OK", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End If

    Me.RadProgressBar1.Value1 = 0
    Me.Label4.Text = ""

End Sub

Public Sub ChangeTexts(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
    Me.Label4.Text = "Downloaded " & Math.Round((position / 1024), 2) & " KB of " & Math.Round((length / 1024), 2) & "KB"
    Me.RadProgressBar1.Value1 = percent
End Sub

Public Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click
    locationfiledownload = GetPage("http://asankonkur.ir/update/locationfiledownload.txt")

    If locationfiledownload <> "" AndAlso locationfiledownload.StartsWith("http://") Then

        Me.SaveFileDialog1.FileName = locationfiledownload.Split("/"c)(locationfiledownload.Split("/"c).Length - 1)
        If Me.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.whereToSave = Me.SaveFileDialog1.FileName
            Me.SaveFileDialog1.FileName = ""

            ToolStripButton2.Enabled = False
            ToolStripButton3.Enabled = True

            Me.BackgroundWorker2.RunWorkerAsync() 'Start download
        End If
    Else
        MessageBox.Show("Please insert valid URL for download", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    End If
End Sub

Private Sub BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
    'Creating the request and getting the response
    Dim theResponse As HttpWebResponse
    Dim theRequest As HttpWebRequest
    Try 'Checks if the file exist

        theRequest = WebRequest.Create(locationfiledownload)
        theResponse = theRequest.GetResponse
    Catch ex As Exception

        MessageBox.Show("An error occurred while downloading file. Possibe causes:" & ControlChars.CrLf & _
                        "1) File doesn't exist" & ControlChars.CrLf & _
                        "2) Remote server error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

        Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
        Me.Invoke(cancelDelegate, True)

        Exit Sub
    End Try
    Dim length As Long = theResponse.ContentLength 'Size of the response (in bytes)

    Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
    Me.Invoke(safedelegate, length, 0, 0, 0) 'Invoke the TreadsafeDelegate

    Dim writeStream As New IO.FileStream(Me.whereToSave, IO.FileMode.Create)
    'Replacement for Stream.Position (webResponse stream doesn't support seek)
    Dim nRead As Integer
    'To calculate the download speed
    Dim speedtimer As New Stopwatch
    Dim currentspeed As Double = -1
    Dim readings As Integer = 0

    Do
        If BackgroundWorker2.CancellationPending Then 'If user abort download
            Exit Do
        End If
        speedtimer.Start()
        Dim readBytes(4095) As Byte
        Dim bytesread As Integer = theResponse.GetResponseStream.Read(readBytes, 0, 4096)

        nRead += bytesread
        Dim percent As Short = (nRead * 100) / length

        Me.Invoke(safedelegate, length, nRead, percent, currentspeed)

        If bytesread = 0 Then Exit Do

        writeStream.Write(readBytes, 0, bytesread)

        speedtimer.Stop()

        readings += 1
        If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
            currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
            speedtimer.Reset()
            readings = 0
        End If
    Loop
    'Close the streams
    theResponse.GetResponseStream.Close()
    writeStream.Close()
    If Me.BackgroundWorker2.CancellationPending Then
        IO.File.Delete(Me.whereToSave)
        Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
        Me.Invoke(cancelDelegate, True)
        Exit Sub
    End If

    Dim completeDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
    Me.Invoke(completeDelegate, False)

End Sub

Private Sub mainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.Label4.Text = ""
End Sub

Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton3.Click
    Me.BackgroundWorker2.CancelAsync() 'Send cancel request
End Sub
4

1 回答 1

2

在您的代码中,您使用的是WebRequest.Create(locationfiledownload). 默认情况下,这会创建一个请求整个文件的请求标头。您需要编辑该请求并添加一个 Range 标头,该标头询问您要查找的文件的特定字节范围。例如,添加到WebRequest.Headers.Range.Ranges集合中。不幸的是,这将使您的代码变得相当复杂,因为您需要在某处存储已经下载的内容的详细信息(假设您想在应用程序关闭/重新启动后恢复)。你需要知道;

  1. 已经下载了多少文件(如果有)
  2. 您打算在任何时候下载多少

一旦你知道了这一点,你将不得不为文件的 X 字节形成一个带有 Range 标头的请求。收到后,您需要保存它并要求下一部分。此处的代码项目中提供了一个用 C# 编写的示例:http: //www.codeproject.com/Tips/307548/Resume-Suppoert-Downloading

于 2013-02-15T16:39:41.713 回答