我试图编写一个将文件拆分成小块的方法, 我试图分割一个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
答案 0 :(得分:1)
使用十六进制编辑器检查拆分部分以及重组文件是否错误。
例如,您可以使用Hex Editor Neo的免费版本:http://www.hhdsoftware.com/free-hex-editor
首先打开原始文件并转到应该进行拆分的偏移量(确保不要将十六进制偏移误认为十进制偏移。图像适用于500 MB部件)。
然后检查并记下偏移之前和之后的值。之前的部分是在Part1中,之后的所有内容都应该在Part2中。
打开这两部分,将Part1末尾和Part2开头的值与原始文件进行比较。他们应该匹配。如果没有,也可以尝试使用专业工具。
如果您的代码不匹配,请尝试我的(请参阅您的其他问题Split a file into chunks larger than 2 GB?)。我只是自己测试它,分裂工作正常。因此,部件的重组似乎存在问题。
答案 1 :(得分:1)
您无法在任意点分割媒体文件。媒体文件具有您将破坏的内部结构。例如,您将在随机位置将视频和音频帧分成两半。
显然,您的播放器可以通过跳过损坏的部分来处理损坏的文件。这就是为什么没有播放你期望的内容。