vb.net - 移动二进制数据直到特定值从一个文件到另一个文件
问题描述
我编写了一个 Visual Basic 应用程序并停留在一个点:
我需要该应用程序读取文件,选择 DDS 字符串之前的所有内容,将其从文件中剪切并粘贴到新文件中。
然后在编辑 DDS 后插入该标题。
问题是,DDS 之前的这个头部没有固定长度:这种类型的每个文件都有不同的头部。我试图弄乱,System.IO.FileStream
但没有结果。
这甚至可能吗?
解决方案
标头长度并不多,一个简单的搜索模式可能就足够了。
传递字节序列以查找文件内部和方法的文件路径FindHeader
。
它返回一个字节数组,其中包含在找到指定序列之前收集的所有字节。
这是一个简单的模式匹配,它向前搜索,直到找到可以匹配指定序列的第一个字节。
然后它读取一个缓冲区并将缓冲区与序列进行比较:
- 如果匹配,则返回该点之前累积的字节;
- 如果不是,它从一个位置的当前[Sequence Length] - 1
位置(在当前流缓冲区内)回溯并继续。
你可以这样称呼它:
Dim closeSequence = New Byte() { &H44, &H44, &H53 }
Dim headerBytes = FindHeader([Source File 1 Path], closeSequence)
现在我们有了第一个源文件的 Header。
第二个源文件的数据部分是:
Dim sourceFile2DataStart = FindHeader([Source File 2 Path], closeSequence).Length + closeSequence.Length
Dim dataLength = New FileInfo([Source File 2 Path]).Length - sourceFile2DataStart
我们需要创建第三个文件,该文件将包含第一个文件的 Header 和从第二个文件读取的数据。
' Create a read buffer. The buffer length is less than or equal to the data length
Dim bufferLength As Integer = CInt(If(dataLength >= 1024, 1024, dataLength))
Dim buffer As Byte() = New Byte(bufferLength - 1) {}
Dim read As Integer = 0
使用两个 FileStream 对象,我们创建一个新的目标文件,写入第一个源文件的标头closeSequence
,标识数据部分的开始,然后我们从第二个源文件读取缓冲区并将缓冲区写入目标文件:
Dim patchworkFilePath as string = [Path of the Destination File]
Using sWriter As FileStream = New FileStream(patchworkFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None),
sReader As FileStream = New FileStream([Source File 2 Path], FileMode.Open, FileAccess.Read, FileShare.None)
sReader.Seek(sourceFile2DataStart, SeekOrigin.Begin)
sWriter.Write(header1Bytes, 0, header1Bytes.Length)
sWriter.Write(closeSequence, 0, closeSequence.Length)
While True
read = sReader.Read(buffer, 0, buffer.Length)
If read = 0 Then Exit While
sWriter.Write(buffer, 0, read)
End While
End Using
标头阅读器方法:
Public Function FindHeader(filePath As String, headerClosure As Byte()) As Byte()
Dim byteToFind = headerClosure(0)
Dim buffer = New Byte(headerClosure.Length - 1) {}
Dim header = New List(Of Byte)(2048)
Dim read As Integer = 0
Using fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None)
While fs.Position <= (fs.Length - headerClosure.Length)
read = fs.ReadByte()
If read = byteToFind Then
fs.Read(buffer, 1, buffer.Length - 1)
buffer(0) = CByte(read)
If buffer.SequenceEqual(headerClosure) Then Exit While
fs.Seek(-(buffer.Length - 1), SeekOrigin.Current)
End If
header.Add(CByte(read))
End While
End Using
Return header.ToArray()
End Function
推荐阅读
- android - Android BottomNavigationBar 每个选项卡的唯一图标色调列表?
- mercurial - 如何从自定义挂钩中读取配置设置?
- java - 如何与加密的 SQS 队列交互?KMS 密钥访问不起作用
- python - 哪种文件处理方式更好:'r' + 'a' 或 'r+'?
- android - 可绘制的正确位置不正确
- tensorflow - pytorch 中 tf.nn.softmax_cross_entropy_with_logits 的等价物是什么?
- yocto - 带有 Yocto 和 GUI 的 Odroid XU4(未找到 gtk+3 错误 wayland-egl)
- node.js - SailsJS / Waterline:仅从关联中获取特定属性
- kotlin - Kotlin 静态库需要在 Windows 下链接到哪些其他库?
- java - android studio开发代码中的执行顺序