复制带有进度的文件

时间:2012-02-04 01:28:39

标签: vb.net

我希望以最有效的方式复制文件,并使用进度条更新复制百分比。

这是我正在使用的标准复制代码:

System.IO.File.Copy(source,target)

这非常快速有效。但是,我无法报告复制百分比。 我尝试了许多函数,通过打开文件流然后在读/写数据时循环来读取和保存文件。这使我能够报告进度。

以下是我正在使用的功能:

    Public Sub SaveBinaryFile(strFilename As String, bytesToWrite() As Byte)
    Dim position As Integer = 0
    Dim BufferSize As Integer = 4096
    'frmMain.tsProgressBar.Value = 0

    Using fsNew As FileStream = New FileStream(strFilename, FileMode.Create, FileAccess.Write)
        Do
            Dim intToCopy As Integer = Math.Min(BufferSize, bytesToWrite.Length - position)
            Dim buffer(intToCopy - 1) As Byte
            Array.Copy(bytesToWrite, position, buffer, 0, intToCopy)
            fsNew.Write(buffer, 0, buffer.Length)
            'frmMain.tsProgressBar.Value = ((position / bytesToWrite.Length) * 100)
            'frmMain.tsProgressBar.Refresh()
            Application.DoEvents()
            position += intToCopy
        Loop While position < bytesToWrite.Length
    End Using
End Sub

Public Function ReadBinaryFile(strFilename As String) As Byte()
    Dim position As Integer = 0
    Dim bufferSize As Integer = 4096
    Dim bytes() As Byte

    'frmMain.tsProgressBar.Value = 0

    Using fsOpen As FileStream = New FileStream(strFilename, FileMode.Open)
        ReDim bytes((fsOpen.Length) - 1)
        Do
            If (position + bufferSize) > fsOpen.Length Then
                fsOpen.Read(bytes, position, fsOpen.Length - position)
                Exit Do
            Else
                fsOpen.Read(bytes, position, bufferSize)
            End If
            'frmMain.tsProgressBar.Value = ((position / fsOpen.Length) * 100)
            'frmMain.tsProgressBar.Refresh()
            Application.DoEvents()
            position += bufferSize
        Loop
    End Using

    Return bytes

End Function

问题在于比使用直接复制代码慢得多。

复制显示复制进度的文件的最佳/有效方法是什么?

谢谢

3 个答案:

答案 0 :(得分:2)

System.IO.File的变体提供用户反馈;它被称为Microsoft.VisualBasic.FileIO.FileSystem。另请参阅http://msdn.microsoft.com/en-us/library/cc165446.aspx

答案 1 :(得分:0)

你可以使用:

System.IO.File.Copy("C:\[Copy From]", "C:\[Copy To]", FileIO.UIOption.AllDialogs)

或者:

Dim CF As New IO.FileStream("C:\[Copy From]", IO.FileMode.Open)
Dim CT As New IO.FileStream("C:\[Copy To]", IO.FileMode.Create)
Dim len As Long = CF.Length - 1
Dim buffer(1024) As Byte
Dim byteCFead As Integer
While CF.Position < len
    byteCFead = (CF.Read(buffer, 0, 1024))
    CT.Write(buffer, 0, byteCFead)
    ProgressBar1.Value = CInt(CF.Position / len * 100)
    Application.DoEvents()
End While
CT.Flush()
CT.Close()
CF.Close()

OR:使用WebClient

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not OpenFileDialog1.ShowDialog() = DialogResult.OK Then Return
If Not FolderBrowserDialog1.ShowDialog = DialogResult.OK Then Return
Button1.Enabled = False
WebClient1.DownloadFileAsync(New Uri(OpenFileDialog1.FileName), Path.Combine(FolderBrowserDialog1.SelectedPath, OpenFileDialog1.SafeFileName))
End Sub

Private Sub WebClient1_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles WebClient1.DownloadProgressChanged
ProgressBar1.Value = e.ProgressPercentage
End Sub

Private Sub WebClient1_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles WebClient1.DownloadFileCompleted
Button1.Enabled = True
End Sub

答案 2 :(得分:0)

嗯尝试此功能

 Dim D As Integer
Function CopyFileWithProgress(ByVal Source As String, ByVal Destination As String) As Integer
    Try

        Dim SourceF As New IO.FileStream(TextBox1.Text, IO.FileMode.Open)
        Dim DestinationF As New IO.FileStream(TextBox2.Text & "\" & TextBox3.Text & ".ps4game", IO.FileMode.Create)
        Dim len As Long = SourceF.Length - 1
        Dim buffer(1024) As Byte
        Dim byteCFead As Integer
        While SourceF.Position < len
            byteCFead = (SourceF.Read(buffer, 0, 1024))
            DestinationF.Write(buffer, 0, byteCFead)
            D = CInt(SourceF.Position / len * 100)
            Application.DoEvents()
        End While
        DestinationF.Flush()
        DestinationF.Close()
        SourceF.Close()
        Return D
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

End Function

它会起作用