此方法将文件拆分为块,我想报告剩余块的进度(百分比)以及完成任务的剩余字节总数。
我把算术操作搞砸了,有人可以帮助我吗?
请在代码中注明我需要报告进度的说明,我使用标签进行测试,我会将值保存在变量中:
Label1.Text = ...
以下是方法:
Public Sub SplitFile(ByVal InputFile As String,
ByVal ChunkSize As Long,
Optional ByVal ChunkName As String = Nothing,
Optional ByVal ChunkExt As String = Nothing,
Optional ByVal Overwrite As Boolean = False)
' FileInfo instance of the input file.
Dim fInfo As New IO.FileInfo(InputFile)
' The buffer to read data and write the chunks.
Dim Buffer As Byte() = New Byte() {}
' The buffer length.
Dim BufferSize As Integer = 1048576I ' 1048576 = 1 mb | 33554432 = 32 mb | 67108864 = 64 mb
' Counts the length of the current chunk file.
Dim BytesWritten As Long = 0L
' The total amount of chunks to create.
Dim ChunkCount As Integer = CInt(Math.Floor(fInfo.Length / ChunkSize))
' Keeps track of the current chunk.
Dim ChunkIndex As Integer = 0I
' A zero-filled string to enumerate the chunk files.
Dim Zeros As String = String.Empty
' The given filename for each chunk.
Dim ChunkFile As String = String.Empty
' The chunk file basename.
ChunkName = If(String.IsNullOrEmpty(ChunkName),
IO.Path.Combine(fInfo.DirectoryName, IO.Path.GetFileNameWithoutExtension(fInfo.Name)),
IO.Path.Combine(fInfo.DirectoryName, ChunkName))
' The chunk file extension.
ChunkExt = If(String.IsNullOrEmpty(ChunkExt),
fInfo.Extension.Substring(1I),
ChunkExt)
' If ChunkSize is bigger than filesize then...
If ChunkSize >= fInfo.Length Then
Throw New OverflowException("'ChunkSize' should be smaller than the Filesize.")
Exit Sub
' For cases where a chunksize is smaller than the buffersize.
ElseIf ChunkSize < BufferSize Then
BufferSize = CInt(ChunkSize)
End If ' ChunkSize <>...
' If not file-overwrite is allowed then...
If Not Overwrite Then
For Index As Integer = 0I To (ChunkCount)
' Set chunk filename.
Zeros = New String("0", CStr(ChunkCount).Length - CStr(Index + 1I).Length)
ChunkFile = String.Format("{0}.{1}.{2}", ChunkName, Zeros & CStr(Index + 1I), ChunkExt)
' If chunk file already exists then...
If IO.File.Exists(ChunkFile) Then
Throw New IO.IOException(String.Format("File already exist: {0}", ChunkFile))
Exit Sub
End If ' IO.File.Exists(ChunkFile)
Next Index
Zeros = String.Empty
ChunkFile = String.Empty
End If ' Overwrite
' Open the file to start reading bytes.
Using InputStream As New IO.FileStream(fInfo.FullName, IO.FileMode.Open)
Using BinaryReader As New IO.BinaryReader(InputStream)
While (InputStream.Position < InputStream.Length)
' Set chunk filename.
Zeros = New String("0", CStr(ChunkCount).Length - CStr(ChunkIndex + 1I).Length)
ChunkFile = String.Format("{0}.{1}.{2}", ChunkName, Zeros & CStr(ChunkIndex + 1I), ChunkExt)
' Reset written byte-length counter.
BytesWritten = 0L
' Create the chunk file to Write the bytes.
Using OutputStream As New IO.FileStream(ChunkFile, IO.FileMode.Create)
Using BinaryWriter As New IO.BinaryWriter(OutputStream)
' Read until reached the end-bytes of the input file.
While (BytesWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
' Read bytes from the original file (BufferSize byte-length).
Buffer = BinaryReader.ReadBytes(BufferSize)
' Write those bytes in the chunk file.
BinaryWriter.Write(Buffer)
' Increment the size counter.
BytesWritten += Buffer.Count
' Use the written bytes of this chunk to calculate the total remaining bytes of the operation (not only for this chunk)...
' Label1.Text = CDbl((100L / ChunkSize) * BytesWritten) / (ChunkIndex / ChunkCount) '/ fInfo.Length
Application.DoEvents()
End While ' (BytesWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
OutputStream.Flush()
End Using ' BinaryWriter
End Using ' OutputStream
ChunkIndex += 1I 'Increment file counter
' Report progress of remaining chunks...
' Label1.Text = CDbl((100I / ChunkCount) * (ChunkIndex))
End While ' InputStream.Position < InputStream.Length
End Using ' BinaryReader
End Using ' InputStream
End Sub
更新:
有了这个,我就可以在创建一个块时打印进度,但是它可以很好地进行,但我们必须将每个块的文件拆分为3 GB,然后我只能报告一些进度变化完成创建块的时间:
Debug.WriteLine(((ChunkIndex) / ChunkCount) * 100I)
这就是我在每个块中写入字节时尝试编写进度报告的原因,这样我可以每秒快速报告进度变化,请注意上面代码中的这部分,这里是我的地方需要帮助:
' Use the written bytes of this chunk to calculate the total remaining bytes of the operation (not only for this chunk)...
' Label1.Text = CDbl((100L / ChunkSize) * BytesWritten) / (ChunkIndex / ChunkCount) '/ fInfo.Length
答案 0 :(得分:1)
一些风格的东西:
以小写字母命名局部变量通常是个好主意。它使您更容易阅读和遵循您的代码。当它们以大写字母开头时,它们会被误认为是方法名称(也许这只是我的偏好)
没有必要使用I
或L
后缀数字。声明变量时,编译器将在您明确指定类型时知道要执行的操作。
回答你的问题:
如果我理解您只想要更精细的进度数据,只需声明一个变量来保存文件的总大小,并减去每个分块缓冲区操作后写入的字节数。添加此声明:
Dim bytesRemaining = fInfo.Length
然后从此处更改While
循环:
While (BytesWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
' Read bytes from the original file (BufferSize byte-length).
Buffer = BinaryReader.ReadBytes(BufferSize)
' Write those bytes in the chunk file.
BinaryWriter.Write(Buffer)
' Increment the size counter.
BytesWritten += Buffer.Count
' Use the written bytes of this chunk to calculate the total remaining bytes of the operation (not only for this chunk)...
' Label1.Text = CDbl((100L / ChunkSize) * BytesWritten) / (ChunkIndex / ChunkCount) '/ fInfo.Length
Application.DoEvents()
End While ' (BytesWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
对此:
While (BytesWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
' Read bytes from the original file (BufferSize byte-length).
Buffer = BinaryReader.ReadBytes(BufferSize)
' Write those bytes in the chunk file.
BinaryWriter.Write(Buffer)
' Increment the size counter.
BytesWritten += Buffer.Count
bytesRemaining -= Buffer.Count
' Use the written bytes of this chunk to calculate the total remaining bytes of the operation (not only for this chunk)...
If bytesRemaining > 0 Then
Label1.Text = (bytesRemaining / fInfo.Length) * 100
End If
Application.DoEvents()
End While ' (BytesWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)
您必须按照您希望的百分比格式。
另外,请注意我没有针对每种可能的情况对此进行测试。可能在最后一个文件中出现了一些疯狂的问题,当它发生时你必须解决这个问题。