删除文件末尾的0x00字节

删除文件末尾的0x00字节

我使用以下方法从 Linux SD 卡中恢复了一些文件(Python、Shell 脚本等,所以只是文本文件)FTK 成像仪精简版0x00。文件没有问题,但它们的末尾现在包含很多字节。

我如何0x00使用我的 Windows 机器批量删除这些尾随字节?

我熟悉该for命令,因此只需建议如何针对一个文件执行此操作即可。然后我可以将其应用于所有文件。

答案1

因为您说您的文件是简单的文本文件,所以我假设所有空字节都可以被删除,无论位于何处。

您可以使用 MORE 命令将每个 \0x00 转换为 \0x0D\0x0A

more yourFile.ext >yourFile.ext.new
move /y yourFile.ext.new yourFile.ext >nul

注意事项:

  • 每个文件必须少于约 64k 行,否则命令将挂起(插入提示并等待 64k 行后的按键)
  • 制表符将转换为空格字符串

一个更强大的替代方案是使用执行文件- 适用于 Windows 的正则表达式文本处理命令行实用程序。它是纯脚本 (JScript/batch),可在 XP 及以上版本的任何 Windows 计算机上本地运行 - 无需第三方 exe 文件。

只要没有文件太大(接近 1GB?),那么您可以使用 /M 选项将整个文件读入内存并对一个大字符串执行搜索/替换操作:

jrepl \x00 "" /m /f yourFile.ext /o -

对于大文件,您可以逐行处理文件,但空字节需要指定输入的字符集,这迫使使用 ADO。标准 JScript 文件输入例程会阻塞包含空字节的行。ADO 解决了这个问题。选择什么字符集并不重要,只要它是单字节字符集即可。

jrepl \x00 "" /f "yourFile.ext|windows-1252" /o -

完整文档内置于 JREPL.BAT 中,可通过jrepl /?jrepl /??获取分页帮助。所有选项的摘要可通过 获取jrepl /?options,所有帮助选项的描述可通过 获取jrepl /?help

JREPL.BAT 仅针对这一项任务就包含大量代码。为此任务编写一个非常小的专用 JScript 或 VBS 脚本并不难。但是,一旦您将 JREPL 纳入您的工具库,您很可能会发现它的很多用途 - 它是一种功能强大的工具。

答案2

PowerShell 解决方案的核心如下所示:

$file = "C:\Users\keith\SomeFile.txt"

$Bytes = [IO.File]::ReadAllBytes($file)

$i = $Bytes.Length - 1

While ($Bytes[$i] -eq 0) { $i-- }

$Bytes = $Bytes[0..$i]

[IO.File]::writeAllBytes($file, $bytes)

更新:在我处理您的代码之前,上面是支持管道的函数,可以处理多个文件。去掉了中间部分$Bytes = $Bytes[0..$i],只在方法中指定了截断的数组[IO.File]::writeAllBytes()。这应该对处理时间有所帮助。

Function Strip-Null {
Param(
  [Parameter(Mandatory,
             ValueFromPipeline,
             ValueFromPipelineByPropertyName,
             Position=0)][SupportsWildcards()]
  [String[]]$Path,
  [Parameter()]
  [Switch]$NoKeepDate=$False
)
  Process{
    ForEach ( $file in $Path ) {
        If ( Test-Path $file ) {
            Resolve-Path $file | ForEach {
                Write-Host "Processing '$file'..." -NoNewline
                $Bytes = [IO.File]::ReadAllBytes($_)
                $i = $Bytes.Length - 1
                While ($Bytes[$i] -eq 0) { $i-- }
                $Dest = $_ -Replace '(\.[^\.]+)$', '_fixed$1'
                [IO.File]::writeAllBytes($dest, $Bytes[0..$i])
                If ( ! ( $NoKeepDate.IsPresent )) {
                    ( Get-Item $dest ).LastWriteTime = ( Get-Item $_ ).LastWriteTime
                }
                Write-Host ( "'{0}' created." -f ( Split-Path $dest -Leaf ))
            }
        } Else { Write-Warning "'$file' is not a valid path." }
    }
  }
}

答案3

如果您知道文件应该在何处(哪个字节)结束(在空字节开始尾随之前),请在该字节后截断(设置文件 EOF)例如。

FSUTIL file seteof <file name> <file size without null trailer>

相关内容