如何使用PowerShell截断已知地址之后的二进制文件内容
最优解决方案(无需正则,更稳定高效)
你已经明确知道需要截断的固定偏移地址,完全不需要使用正则绕弯路,直接截取偏移之前的字节写入输出文件即可,代码可以大幅简化,且兼容Win7/Win10原生PowerShell环境:
$inputFile = 'C:\StartFile.dat' $outputFile = 'C:\EndFile_test.dat' # 十进制截断偏移,对应十六进制地址0x005A08B0 $truncateOffset = 5900464 # 小文件直接读取全量字节截断即可 $fileBytes = [System.IO.File]::ReadAllBytes($inputFile) # 仅保留偏移0到$truncateOffset-1的字节(数组下标从0开始,$truncateOffset位置为要删除的起始字节) $reservedBytes = $fileBytes[0..($truncateOffset - 1)] [System.IO.File]::WriteAllBytes($outputFile, $reservedBytes) Write-Host "截断完成,共保留$truncateOffset字节内容"
如果需要处理GB级大文件避免内存溢出,可以用流操作版本:
$inputFile = 'C:\StartFile.dat' $outputFile = 'C:\EndFile_test.dat' $truncateOffset = 5900464 $inStream = New-Object System.IO.FileStream($inputFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) $outStream = New-Object System.IO.FileStream($outputFile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write) $buffer = New-Object byte[] 4096 $bytesToRead = $truncateOffset while ($bytesToRead -gt 0) { $read = $inStream.Read($buffer, 0, [Math]::Min($buffer.Length, $bytesToRead)) if ($read -eq 0) { break } $outStream.Write($buffer, 0, $read) $bytesToRead -= $read } $inStream.Close() $outStream.Close() Write-Host "大文件截断完成,共保留$($truncateOffset - $bytesToRead)字节内容"
原有正则方案修复(仅作参考,不推荐)
你原有正则的核心错误是把\x开头的字节值当成了偏移地址,字符组[\x5A08B0]实际是匹配\x5A、\x08、\xB0三个单字节中的任意一个,和偏移位置无关。如果坚持要用正则方案,正确写法如下:
# (?s)开启单行模式,让.可以匹配所有字节,匹配从第5900464个字节开始到结尾的所有内容 $re = [Regex]'(?s)^.{5900464}(.*)$' # 替换后仅保留前5900464个字节 $binString = $re.Replace($binString, '$1')
该方案处理大文件性能远低于直接截断方案,且容易出现编码匹配问题,不建议使用。
内容的提问来源于stack exchange,提问作者k1dfr0std
相关产品推荐
相关产品推荐

