1

1 つのファイルの最後に多数のファイルを追加するアプリケーションを作成しています...ファイル全体をメモリにロードすることを避けるために、バッファを指定して filestream クラスを使用していますが、進行状況を表示したいと考えています。コピーされる個々のファイルと現在のファイルの名前...これは簡単ですが、各ファイルが非常に小さい場合、foreachループシーム内で実行するとパフォーマンスが大幅に低下します。

コードは次のとおりです。

  Public Function StreamAppendFileToFile(ByVal f1 As String, ByVal f2 As String)
        Dim bytesRead As Integer
        Dim nn As New FileInfo(f1)
        CurrentFsize = nn.Length

        Dim buffer(40096) As Byte
        Using inFile As New System.IO.FileStream(f1, IO.FileMode.Open, IO.FileAccess.Read)
            Using outFile As New System.IO.FileStream(f2, IO.FileMode.Append, IO.FileAccess.Write)
                Do
                    bytesRead = inFile.Read(buffer, 0, 40096)
                    outFile.Write(buffer, 0, bytesRead)
                    Application.DoEvents()
                Loop While bytesRead > 0
            End Using
        End Using
    End Function

このようなものを入れると、実行時間が2倍になります:

Public Function StreamAppendFileToFile(ByVal f1 As String, ByVal f2 As String)
        Dim bytesRead As Integer
        Dim nn As New FileInfo(f1)
        CurrentFsize = nn.Length

        Dim buffer(40096) As Byte
        Using inFile As New System.IO.FileStream(f1, IO.FileMode.Open, IO.FileAccess.Read)
            Using outFile As New System.IO.FileStream(f2, IO.FileMode.Append, IO.FileAccess.Write)
                Do
                    bytesRead = inFile.Read(buffer, 0, 40096)
                    **Progressbar1.value = Math.Round((bytesRead / CurrentFsize) * 100)**
                    **Application.Doevents()**
                    outFile.Write(buffer, 0, bytesRead)
                    Application.DoEvents()
                Loop While bytesRead > 0
            End Using
        End Using
    End Function

あるファイルを別のファイルにストリーム追加し、進行状況を表示するという点で、これを行うためのより良い/より高速/より効率的な方法はありますか? ありがとう..

4

1 に答える 1

4

操作に時間がかかる場合は、操作を別のスレッドに移動することをお勧めします。たとえば、 を使用BackgroundWorkerしてこれを行うことができます (また、イベントを使用しDoWorkてアクションを実行し、イベントを使用しProgressChangedて進行状況を UI に報告します)。

コード例:

まず、 があり、BackgroundWorker進行状況を報告するように設定されていることを確認します (プロパティWorkerReportsProgressを に設定することによりTrue) 。

' This class is used to pass the information to the BackgroundWorker DoWork event
Private Class IOFilesInfo
    Public Property InFile As String
    Public Property OutFile As String
End Class

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    ' Start the BackgroundWorker if it isn't started yet
    If Not BackgroundWorker1.IsBusy Then
        Dim filesInfo As New IOFilesInfo() With {.InFile = "in.txt", .OutFile = "out.txt"}
        BackgroundWorker1.RunWorkerAsync(filesInfo)
    End If
End Sub

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    Dim filesInfo As IOFilesInfo = DirectCast(e.Argument, IOFilesInfo)

    ' Get the file info for the input file (the filesize)
    Dim inFileFileInfo As New FileInfo(filesInfo.InFile)
    Dim inFileFileSize As Long = inFileFileInfo.Length

    ' Keep the progress, total amount of bytes read => you could also keep the progress percentage
    Dim totalBytesRead As Integer = 0

    Dim bytesRead As Integer
    Dim buffer(10) As Byte
    Using inFile As New System.IO.FileStream(filesInfo.InFile, IO.FileMode.Open, IO.FileAccess.Read)
        Using outFile As New System.IO.FileStream(filesInfo.OutFile, IO.FileMode.Append, IO.FileAccess.Write)
            Do
                bytesRead = inFile.Read(buffer, 0, 10)
                outFile.Write(buffer, 0, bytesRead)

                ' Add the bytesRead to the total and report the progress as a percentage
                totalBytesRead += bytesRead
                worker.ReportProgress(Convert.ToInt32(totalBytesRead \ inFileFileSize) * 100)
            Loop While bytesRead > 0
        End Using
    End Using
End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    ProgressBar1.Value = e.ProgressPercentage
End Sub
于 2013-06-17T21:13:05.407 に答える