.net 我的filespliter方法无法正确写入数据

.net 我的filespliter方法无法正确写入数据,.net,vb.net,file,split,stream,.net,Vb.net,File,Split,Stream,我想写一个方法把一个文件分成小块, 我曾尝试分割一个6,67 mb、2,55分钟长的MP3音频文件,但如果我将分割的部分(虚拟地在播放器中)合并,合并的文件的长度将小于2:53分钟,这种情况总是会发生,当要分割的文件的持续时间更大时(比如说30:00分钟的MP3文件),分割的文件的持续时间将更小(比如说29:40分钟) 此外,在播放器中,当轨道的一个分割部分发生变化时,我可以注意到声音“跳跃”了几毫秒,因此没有正确地“对齐/同步”,似乎分割的部分在开始时会吃掉声音 拆分文件的文件大小与原始文件相

我想写一个方法把一个文件分成小块, 我曾尝试分割一个6,67 mb、2,55分钟长的MP3音频文件,但如果我将分割的部分(虚拟地在播放器中)合并,合并的文件的长度将小于2:53分钟,这种情况总是会发生,当要分割的文件的持续时间更大时(比如说30:00分钟的MP3文件),分割的文件的持续时间将更小(比如说29:40分钟)

此外,在播放器中,当轨道的一个分割部分发生变化时,我可以注意到声音“跳跃”了几毫秒,因此没有正确地“对齐/同步”,似乎分割的部分在开始时会吃掉声音

拆分文件的文件大小与原始文件相同,但显然所有数据都没有正确写入

因此,我的方法在读取或写入字节时,在末尾或开头缺少一些字节,我不知道在哪里,如何修复这个问题

我已经验证了在使用各种专业文件拆分器时不会发生这种情况,这不是播放器的问题,而是我代码中的一个bug。

方法如下:

Public Sub SplitFile(ByVal InputFile As String,
                     ByVal ChunkSize As Long,
                     Optional ByVal ChunkName As String = Nothing,
                     Optional ByVal ChunkExt As String = Nothing)

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

    ' The total amount of chunks to create.
    Dim ChunkCount As Integer = CInt(Math.Floor(fInfo.Length / ChunkSize))

    ' The remaining bytes of the last chunk.
    Dim LastChunkSize As Long = fInfo.Length - (ChunkCount * ChunkSize)

    ' The Buffer to read the chunks.
    Dim ChunkBuffer As Byte() = New Byte(ChunkSize - 1L) {}

    ' The Buffer to read the last chunk.
    Dim LastChunkBuffer As Byte() = New Byte(LastChunkSize - 1L) {}

    ' 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)

    ' 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)

            BinaryReader.BaseStream.Seek(0L, IO.SeekOrigin.Begin)

            For ChunkIndex As Integer = 0I To ChunkCount

                Zeros = New String("0", CStr(ChunkCount).Length - CStr(ChunkIndex + 1).Length)
                ChunkFile = String.Format("{0}.{1}.{2}", ChunkName, Zeros & CStr(ChunkIndex + 1I), ChunkExt)

                If ChunkIndex <> ChunkCount Then ' Read the ChunkSize bytes.
                    InputStream.Position = (ChunkSize * CLng(ChunkIndex))
                    BinaryReader.Read(ChunkBuffer, 0I, ChunkSize)

                Else ' Read the remaining bytes of the LastChunkSize.
                    InputStream.Position = (ChunkSize * ChunkIndex) + 1
                    BinaryReader.Read(LastChunkBuffer, 0I, LastChunkSize)

                End If ' ChunkIndex <> ChunkCount

                ' 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)

                        If ChunkIndex <> ChunkCount Then
                            BinaryWriter.Write(ChunkBuffer)
                        Else
                            BinaryWriter.Write(LastChunkBuffer)
                        End If

                        OutputStream.Flush()

                    End Using ' BinaryWriter

                End Using ' OutputStream

                ' Report the progress...
                ' RaiseEvent ProgressChanged(CDbl((100I / ChunkCount) * ChunkIndex))

            Next ChunkIndex

        End Using ' BinaryReader

    End Using ' InputStream

End Sub
公共子拆分文件(ByVal InputFile作为字符串,
ByVal块大小与长度相同,
可选的ByVal ChunkName作为String=Nothing,
可选的ByVal ChunkExt As String=Nothing)
'输入文件的FileInfo实例。
将fInfo设置为新IO.FileInfo(InputFile)
'要创建的块的总数。
Dim ChunkCount As Integer=CInt(Math.Floor(fInfo.Length/ChunkSize))
'最后一个块的剩余字节。
Dim LastChunkSize As Long=fInfo.Length-(ChunkCount*ChunkSize)
'读取块的缓冲区。
Dim ChunkBuffer As Byte()=新字节(ChunkSize-1L){}
'读取最后一个块的缓冲区。
Dim LastChunkBuffer As Byte()=新字节(LastChunkSize-1L){}
'枚举区块文件的零填充字符串。
调零为String=String.Empty
'每个块的给定文件名。
Dim ChunkFile As String=String.Empty
'块文件basename。
ChunkName=If(String.IsNullOrEmpty(ChunkName)),
IO.Path.Combine(fInfo.DirectoryName,IO.Path.GetFileNameWithoutExtension(fInfo.Name)),
IO.Path.Combine(fInfo.DirectoryName,ChunkName))
'块文件扩展名。
ChunkExt=If(String.IsNullOrEmpty(ChunkExt),
fInfo.Extension.Substring(1I),
(文本)
'打开文件以开始读取字节。
将InputStream用作新的IO.FileStream(fInfo.FullName、IO.FileMode.Open)
将BinaryReader用作新IO.BinaryReader(InputStream)
BinaryReader.BaseStream.Seek(0L,IO.SeekOrigin.Begin)
对于ChunkIndex作为整数=0I的ChunkCount
零=新字符串(“0”,CStr(ChunkCount).Length-CStr(ChunkIndex+1).Length)
ChunkFile=String.Format(“{0}.{1}.{2}”),ChunkName,Zeros&CStr(ChunkIndex+1I),ChunkExt)
如果ChunkIndex ChunkCount,则“读取ChunkSize字节”。
InputStream.Position=(ChunkSize*CLng(ChunkIndex))
BinaryReader.Read(ChunkBuffer,0I,ChunkSize)
Else'读取LastChunkSize的剩余字节。
InputStream.Position=(ChunkSize*ChunkIndex)+1
BinaryReader.Read(LastChunkBuffer,0I,LastChunkSize)
如果'ChunkIndex ChunkCount'结束
'创建区块文件以写入字节。
将OutputStream用作新的IO.FileStream(ChunkFile、IO.FileMode.Create)
将BinaryWriter用作新IO.BinaryWriter(OutputStream)
如果ChunkIndex ChunkCount那么
BinaryWriter.Write(ChunkBuffer)
其他的
BinaryWriter.Write(LastChunkBuffer)
如果结束
OutputStream.Flush()
结束使用“BinaryWriter”
结束使用“OutputStream”
“报告进展。。。
'RaiseEvent ProgressChanged(CDbl((100I/ChunkCount)*ChunkIndex))
下一个块索引
结束使用“二进制读取器”
使用“InputStream”结束
端接头

使用十六进制编辑器检查拆分的部分以及重新组合的文件是否存在错误

例如,您可以使用免费版本的Hex Editor Neo:

首先打开原始文件,转到应该发生拆分的偏移量(确保不要将十六进制偏移量误认为十进制偏移量。图像用于500 MB的部分)

然后检查并记录偏移前后的值。之前的所有内容都在第1部分中,之后的所有内容都应该在第2部分中

打开这两个部分,将第1部分末尾和第2部分开头的值与原始文件进行比较。它们应该匹配。如果不匹配,也可以使用专业工具进行相同的尝试


如果您的代码不匹配,请尝试我的(参见其他问题)。我自己刚测试过,分割效果很好。因此,部件的重组似乎有问题。

您无法在任意点分割媒体文件。媒体文件具有内部结构,您将破坏这些结构。例如,您将在任意位置将视频和音频帧分割成两半


显然,您的播放机可以通过跳过断开的部分来处理断开的文件。这就是为什么没有播放您所期望的内容。

我知道他的媒体播放机有一些功能,可以通过内部重新组合来播放断开的文件。在这种情况下,您的论点无关紧要。但是,如果他试图播放每个文件,那么你完全正确。我真的愚蠢地认为mp3文件不一定需要典型的mp3偏移来播放其内容,但我使用了“mp3val”工具来修复mp3 pr