我编写了一个将文件拆分为小块(here)的方法,这是合并这些拆分块的方法。
我遇到的问题是进度报告,ChunkProgress
值的计算错误:
每个块应该从0%到100%。
我该如何解决?
这就是我获得价值的方式:
ChunkProgress = (100I / InputStream.Length) * (SizeWritten - BufferLength)
InputStream.Length =当前块的大小(以字节为单位)。
SizeWritten =来自第一个块的写入字节总数。
BufferLength =用于读/写字节的固定缓冲区大小(在本例中为1兆字节)
这是相关代码:
''' <summary>
''' Gets or sets the buffer-size to split or merge, in Bytes.
''' Default value is: 1048576 bytes (1 megabyte).
''' </summary>
''' <value>The buffer-size.</value>
Public Property BufferSize As Integer = 1048576I
''' <summary>
''' Merges the specified file.
''' </summary>
''' <param name="InputFile">
''' Indicates the file to merge its chunks.
''' This should be the first chunk file (eg: 'File.Part.01.mkv')
''' </param>
''' <param name="OutputFile">Indicates the output file.</param>
''' <param name="Overwrite">
''' If set to <c>true</c> the chunks will be deleted after a successful merge,
''' otherwise, an exception will be thrown.
''' </param>
''' <exception cref="System.IO.IOException">File already exist</exception>
Public Sub Merge(ByVal InputFile As String,
Optional ByVal OutputFile As String = Nothing,
Optional ByVal Overwrite As Boolean = False,
Optional DeleteChunksAfterMerged As Boolean = False)
If Not File.Exists(InputFile) Then
Throw New FileNotFoundException("The specified file doesn't exists.", InputFile)
Exit Sub
ElseIf Not Overwrite AndAlso File.Exists(OutputFile) Then
Throw New IOException(String.Format("File already exist: {0}", OutputFile))
Exit Sub
End If
' The progress event arguments.
Dim ProgressArguments As MergeProgressChangedArgs
' FileInfo instance of the input chunk file.
Dim fInfo As New FileInfo(InputFile)
' Get the filename without extension.
Dim Filename As String = Path.GetFileNameWithoutExtension(fInfo.FullName)
' Remove the chunk enumeration from the filename.
Filename = Filename.Substring(0I, Filename.LastIndexOf("."c))
' TSet the pattern to find the chunk files to merge.
Dim ChunkPatternSearch As String =
Filename & ".*" & If(Not String.IsNullOrEmpty(fInfo.Extension), fInfo.Extension, "")
' Retrieve all the splitted files to merge them.
Dim Chunks As IEnumerable(Of FileInfo) =
From Chunk As String In
Directory.GetFiles(fInfo.DirectoryName, ChunkPatternSearch, SearchOption.TopDirectoryOnly)
Select New FileInfo(Chunk)
' The total filesize to merge, in bytes.
Dim TotalSize As Long =
(From Chunk As FileInfo In Chunks Select Chunk.Length).Sum
' The remaining size to calculate the percentage, in bytes.
Dim SizeRemaining As Long = TotalSize
' Counts the length of the current chunk file to calculate the percentage, in bytes.
Dim SizeWritten As Long = 0L
' The buffer to read data and merge the chunks.
Dim Buffer As Byte() = New Byte() {}
' The buffer length.
Dim BufferLength As Integer = Me.BufferSize
' The total amount of chunks to merge.
Dim ChunkCount As Integer = Chunks.Count
' Keeps track of the current chunk.
Dim ChunkIndex As Integer = 0I
' Keeps track of the total percentage done.
Dim TotalProgress As Double = 0.0R
' Keeps track of the current chunk percentage done.
Dim ChunkProgress As Double = 0.0R
' Create the output file to merge the chunks inside.
Using OutputStream As New FileStream(OutputFile, FileMode.Create)
Using BinaryWriter As New BinaryWriter(OutputStream)
' Iterate the chunks.
For Each Chunk As FileInfo In Chunks
' Open the chunk to start reading bytes.
Using InputStream As New FileStream(Chunk.FullName, FileMode.Open)
Using BinaryReader As New BinaryReader(InputStream)
' Read until reached the end-bytes of the chunk file.
While (InputStream.Position < InputStream.Length)
' Read bytes from the chunk file (BufferSize byte-length).
Buffer = BinaryReader.ReadBytes(BufferLength)
' Write those bytes in the output file.
BinaryWriter.Write(Buffer)
' Increment the bytes-written counter.
SizeWritten += Buffer.Count
' Decrease the bytes-remaining counter.
SizeRemaining -= Buffer.Count
TotalProgress = (TotalSize - SizeRemaining) * (100I / TotalSize)
ChunkProgress = (100I / InputStream.Length) * (SizeWritten - BufferLength)
' (100I / InputStream.Length) * (SizeWritten - BufferLength)
' Set the progress event-arguments.
ProgressArguments = New MergeProgressChangedArgs(
TotalProgress:=TotalProgress,
ChunkProgress:=ChunkProgress,
ChunksToMerge:=ChunkCount,
ChunksMerged:=ChunkIndex)
' Report the progress.
RaiseEvent MergeProgressChanged(Me, ProgressArguments)
End While ' (InputStream.Position < InputStream.Length)
ChunkIndex += 1I 'Increment the chunk file counter.
End Using ' BinaryReader
End Using ' InputStream
Next Chunk
OutputStream.Flush()
End Using ' BinaryWriter
End Using ' OutputStream
If DeleteChunksAfterMerged Then ' Delethe the chunk files.
For Each Chunk As FileInfo In Chunks
File.Delete(Chunk.FullName)
Next Chunk
End If ' DeleteChunksAfterMerged
End Sub
答案 0 :(得分:2)
您需要这个来计算整个文件的百分比:
' Increment the bytes-written counter.
SizeWritten += Buffer.Count
但它在报告块进度方面没有任何作用。如果你看一下GIF,你会在它开始编写块#2的那一刻看到它提示超过100%,然后当你开始做块3时再次提示为200%。要修复它,你需要一个新的ChunkBytesWritten类型var:
' Increment the bytes-written counter.
SizeWritten += Buffer.Count
ChunkBytes+= Buffer.Count
然后在ChunkIndex更改时重置它:
ChunkIndex += 1
ChunkBytes = 0
然后计算应该是:
ChunkProgress = (100I / InputStream.Length) * (ChunkBytes - BufferLength)