Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 修复此方法中的进度报告事件_.net_Vb.net_Math_Byte_Progress - Fatal编程技术网

.net 修复此方法中的进度报告事件

.net 修复此方法中的进度报告事件,.net,vb.net,math,byte,progress,.net,Vb.net,Math,Byte,Progress,我曾尝试编写一种方法,将文件拆分为更小的部分(我称这些部分为“块”),我使用1 MB的缓冲区读取/写入块,并报告操作进度百分比和当前块进度百分比 问题是,我有一个6,74 GB的大文件,我会将它分成每个1 GB的块,进度报告按预期工作,但不适用于最后一个块,其中进度仅高达75%。当然,最后一个部分约为750 mb,而不是1 GB,那么最后一个块中的进度仅显示为75% 这就是我获取百分比的方式,错误的进度是Else块中的ChunkProgress值: If Not ChunkIndex = Chu

我曾尝试编写一种方法,将文件拆分为更小的部分(我称这些部分为“块”),我使用1 MB的缓冲区读取/写入块,并报告操作进度百分比和当前块进度百分比

问题是,我有一个6,74 GB的大文件,我会将它分成每个1 GB的块,进度报告按预期工作,但不适用于最后一个块,其中进度仅高达75%。当然,最后一个部分约为750 mb,而不是1 GB,那么最后一个块中的进度仅显示为75%

这就是我获取百分比的方式,错误的进度是
Else
块中的
ChunkProgress
值:

If Not ChunkIndex = ChunkCount Then
    ProgressArguments =
        New SplitProgressChangedArgs(
            TotalProgress:=(TotalSize - SizeRemaining) * (100I / TotalSize),
            ChunkProgress:=(100I / ChunkSize) * (SizeWritten - BufferLength),
            ChunksToCreate:=ChunkCount + 1,
            ChunksCreated:=ChunkIndex)

Else
    ProgressArguments =
        New SplitProgressChangedArgs(
            TotalProgress:=(TotalSize - SizeRemaining) * (100I / TotalSize) - 1.0R,
            ChunkProgress:=(100I / ChunkSize) * (SizeWritten - InputStream.Length),
            ChunksToCreate:=ChunkCount + 1,
            ChunksCreated:=ChunkIndex)

End If
TotalSize=被拆分文件的固定大小,以字节为单位(在本例中为6,74 gb)

ChunkSize=块的固定大小,以字节为单位(在本例中为1 GB)

SizeMaining=剩余的总大小计数器,以字节为单位(在本例中为6,74 gb到0)

SizeWrited=块大小写入计数器,以字节为单位(在本例中为0到1 GB)

有人能帮我在写最后一块时确定百分比吗

这是该类别的相关代码:

''' <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>
''' Splits the specified file.
''' </summary>
''' <param name="InputFile">Indicates the file to split.</param>
''' <param name="ChunkSize">Indicates the size of each chunk.</param>
''' <param name="ChunkName">Indicates the name-format for the chunks.</param>
''' <param name="ChunkExt">Indicates the file-extension for the chunks.</param>
''' <param name="Overwrite">
''' If set to <c>true</c> any existing file will be overwritten if needed to create a chunk, 
''' otherwise, an exception will be thrown.
''' </param>
''' <param name="DeleteAfterSplit">If set to <c>true</c> the input file will be deleted after a successful split.</param>
''' <exception cref="System.OverflowException">'ChunkSize' should be smaller than the Filesize.</exception>
''' <exception cref="System.IO.IOException">File already exist</exception>
Public Sub Split(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,
                 Optional ByVal DeleteAfterSplit As Boolean = False)

    ' The progress event arguments.
    Dim ProgressArguments As SplitProgressChangedArgs

    ' FileInfo instance of the input file.
    Dim fInfo As New FileInfo(InputFile)

    ' The total filesize to split, in bytes.
    Dim TotalSize As Long = fInfo.Length

    ' 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 write the chunks.
    Dim Buffer As Byte() = New Byte() {}

    ' The buffer length.
    Dim BufferLength As Integer = Me.BufferSize

    ' 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),
                   Path.Combine(fInfo.DirectoryName, Path.GetFileNameWithoutExtension(fInfo.Name)),
                   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 < BufferLength Then
        BufferLength = 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 File.Exists(ChunkFile) Then

                Throw New IOException(String.Format("File already exist: {0}", ChunkFile))
                Exit Sub

            End If ' 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 FileStream(fInfo.FullName, FileMode.Open)

        Using BinaryReader As New 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.
                SizeWritten = 0L

                ' Create the chunk file to Write the bytes.
                Using OutputStream As New FileStream(ChunkFile, FileMode.Create)

                    Using BinaryWriter As New BinaryWriter(OutputStream)

                        ' Read until reached the end-bytes of the input file.
                        While (SizeWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)

                            ' Read bytes from the original file (BufferSize byte-length).
                            Buffer = BinaryReader.ReadBytes(BufferLength)

                            ' Write those bytes in the chunk file.
                            BinaryWriter.Write(Buffer)

                            ' Increment the bytes-written counter.
                            SizeWritten += Buffer.Count

                            ' Decrease the bytes-remaining counter.
                            SizeRemaining -= Buffer.Count

                            If Not ChunkIndex = ChunkCount Then
                                ProgressArguments =
                                    New SplitProgressChangedArgs(
                                        TotalProgress:=(TotalSize - SizeRemaining) * (100I / TotalSize),
                                        ChunkProgress:=(100I / ChunkSize) * (SizeWritten - BufferLength),
                                        ChunksToCreate:=ChunkCount + 1,
                                        ChunksCreated:=ChunkIndex)

                            Else
                                ProgressArguments =
                                    New SplitProgressChangedArgs(
                                        TotalProgress:=(TotalSize - SizeRemaining) * (100I / TotalSize) - 1.0R,
                                        ChunkProgress:=(100I / ChunkSize) * (SizeWritten - InputStream.Length),
                                        ChunksToCreate:=ChunkCount + 1,
                                        ChunksCreated:=ChunkIndex)

                            End If

                            ' Report the progress.
                            RaiseEvent SplitProgressChanged(Me, ProgressArguments)

                        End While ' (SizeWritten < ChunkSize) AndAlso (InputStream.Position < InputStream.Length)

                        OutputStream.Flush()

                    End Using ' BinaryWriter

                End Using ' OutputStream

                ChunkIndex += 1I 'Increment the chunk file counter.

            End While ' InputStream.Position < InputStream.Length

        End Using ' BinaryReader

    End Using ' InputStream

End Sub

进度不能正确显示在最后一个块上的原因是,您正在根据“正常”块大小计算进度

例如(使用简化值):

如果最后一个块只有750个字节,我们必须通过除以
(thisChunk/ChunkSize)
进行更正:

对于
Else
案例,请尝试此操作
(InputStream.Length-sizewrited)
应获取剩余块的大小:

ProgressArguments =
  New SplitProgressChangedArgs(
  TotalProgress:=(TotalSize - SizeRemaining) * (100I / TotalSize) - 1.0R,
  ChunkProgress:=(100I / ChunkSize) * (SizeWritten - InputStream.Length) / ((InputStream.Length - SizeWritten) / ChunkSize),
  ChunksToCreate:=ChunkCount + 1,
  ChunksCreated:=ChunkIndex)

感谢您的帮助,但值始终为“-100”,我试图注意到您提供的操作中有什么问题,但我找不到问题所在。请注意:“inputstream.length”的值与“TotalSize”的值(在本例中为6,74 gb)相同,可能这就是问题所在,因为我无法(或不知道如何)获取最后一个块的大小,可能这是必要的因素。这是获取最后一个大小块(750 mb)的计算:(inputstream.length-(ChunkSize*ChunkIndex))完成:(100I/(InputStream.Length-(ChunkSize*ChunkIndex))*(sizewrited-BufferLength)这就是您现在期望的输出吗?没问题。我会找你的新问题,看看能不能帮你一把。
500 out of 1000 bytes with ChunkSize = 1000
500 / ChunkSize = %
500/1000 = 0.5
500 out of 750 bytes with ChunkSize = 1000
500 / ChunkSize / (thisChunk / ChunkSize) = %
500/1000 / (750/1000) = 0.667
ProgressArguments =
  New SplitProgressChangedArgs(
  TotalProgress:=(TotalSize - SizeRemaining) * (100I / TotalSize) - 1.0R,
  ChunkProgress:=(100I / ChunkSize) * (SizeWritten - InputStream.Length) / ((InputStream.Length - SizeWritten) / ChunkSize),
  ChunksToCreate:=ChunkCount + 1,
  ChunksCreated:=ChunkIndex)