查找文件中最后一次出现的ASCII字节并从该点到结尾截断文件?

时间:2018-12-01 21:46:15

标签: truncate

在Windows命令行环境中,我希望能够搜索二进制文件以查找最后(最终)出现的十六进制06字符(“ Ack”),并将文件从该char截断到末尾。文件,表示找到的字符也被修剪掉。我怎样才能做到这一点?这些文件的大小可能为数百兆字节。

编辑:为了公平起见,我在代码搜索方面做了很多Google搜寻工作,但是我的搜索字词并未带给我解决该问题的某种方式。诸如“搜索二进制文件以查找ASCII char hex 06,找到该char的最后一次出现并从该点开始截断文件”之类的内容如此含糊,以至于基本上没有用。我会继续寻找!

1 个答案:

答案 0 :(得分:0)

如果您开始从文件的 end 中读取字节,则会找到 last ACK(如果有的话)。知道了它的位置,您现在可以截断该文件。

我不擅长PowerShell,所以可能有些我不知道的cmdlet,但这可以实现您想要的:

$filename = "C:\temp\FindAck.txt"
$file = Get-Item $filename
$len = $file.Length
$blockSize = 32768
$buffer = new-object byte[] $blockSize

$found = $false
$blockNum = [math]::floor($len / $blockSize)

$mode = [System.IO.FileMode]::Open
$access = [System.IO.FileAccess]::Read
$sharing = [IO.FileShare]::Read
$fs = New-Object IO.FileStream($filename, $mode, $access, $sharing)

$foundPos = -1

while (!$found -and $blockNum -ge 0) {
    $fs.Position = $blockNum * $blockSize
    $bytesRead = $fs.Read($buffer, 0, $blocksize)
    if ($bytesRead -gt 0) {
        for ($i = $bytesRead -1; $i -ge 0; $i--) {
            if ($buffer[$i] -eq 6) {
                $foundPos = $blockNum * $blockSize + $i
                $found = $true
                break
            }
        }
    }
    $blockNum--
}

$fs.Dispose()

if ($foundPos -ne -1) {
    $mode = [System.IO.FileMode]::Open
    $access = [System.IO.FileAccess]::Write
    $sharing = [IO.FileShare]::Read

    $fs = New-Object IO.FileStream($filename, $mode, $access, $sharing)
    $fs.SetLength($foundPos)
    $fs.Dispose()
}

Write-Host $foundPos

读取32KB块的想法是从磁盘上获取适当大小的块以进行处理,而不是一次读取一个字节。


参考文献: