我的FileSplitter方法不能正确写入数据

时间:2014-08-10 07:18:14

标签: .net vb.net file split stream

我试图编写一个将文件拆分成小块的方法, 我试图分割一个6,67 mb和2,55分钟长度的MP3音频文件,但是如果我合并分割的部分(在播放器中很有用),合并文件的长度小于2:53分钟,这个总是发生,当要拆分的文件的持续时间更长时(假设是30:00分钟的mp3文件),拆分文件的持续时间更小(比方说29:40分钟)。

此外,在播放器中,当曲目的一个分割部分发生变化时,我可以注意到声音"跳跃"几毫秒所以不正确"分配/同步",似乎分裂的部分在开始时吃声音。

分割文件的文件大小等于原始文件,但很明显所有数据都没有正确写入。

所以我的方法在读取或写入字节时在结尾或开始时缺少一些字节,我不知道在哪里,我如何解决这个问题?

我已经确认当我使用各种专业文件分割器时不会发生这种情况,这不是播放器的问题,是我代码中的错误。

这是方法:

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

2 个答案:

答案 0 :(得分:1)

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

例如,您可以使用Hex Editor Neo的免费版本:http://www.hhdsoftware.com/free-hex-editor

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

enter image description here

然后检查并记下偏移之前和之后的值。之前的部分是在Part1中,之后的所有内容都应该在Part2中。

enter image description here

打开这两部分,将Part1末尾和Part2开头的值与原始文件进行比较。他们应该匹配。如果没有,也可以尝试使用专业工具。

如果您的代码不匹配,请尝试我的(请参阅您的其他问题Split a file into chunks larger than 2 GB?)。我只是自己测试它,分裂工作正常。因此,部件的重组似乎存在问题。

答案 1 :(得分:1)

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

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