【问题标题】:In Powershell, How do I split a large binary file?在 Powershell 中,如何拆分大型二进制文件?
【发布时间】:2014-07-11 06:50:41
【问题描述】:

我已经在其他地方看到了文本文件的答案,但我需要为压缩文件执行此操作。

我有一个 6G 的二进制文件,需要分成 100M 个块。我是否在某处错过了 unix“头”的模拟?

【问题讨论】:

标签: powershell


【解决方案1】:

没关系。给你:

function split($inFile,  $outPrefix, [Int32] $bufSize){

  $stream = [System.IO.File]::OpenRead($inFile)
  $chunkNum = 1
  $barr = New-Object byte[] $bufSize

  while( $bytesRead = $stream.Read($barr,0,$bufsize)){
    $outFile = "$outPrefix$chunkNum"
    $ostream = [System.IO.File]::OpenWrite($outFile)
    $ostream.Write($barr,0,$bytesRead);
    $ostream.close();
    echo "wrote $outFile"
    $chunkNum += 1
  }
}

假设:bufSize 适合内存。

【讨论】:

  • 为什么我们需要$stream.seek? Read 方法会自动设置当前位置,对吧?
  • 你可能是对的,@Samik。如果您可以对其进行测试以确保其正常工作,我将删除该行代码。
  • 是的,我注释掉了涉及 $curOffset 的三行代码,它也同样有效。当我使用这个脚本来分割一个文本文件时,我不得不添加几行代码,这样它就不会在一行中间中断。无论如何,谢谢你的代码。
【解决方案2】:

推论问题的答案:如何将它们重新组合在一起?

function stitch($infilePrefix, $outFile) {

    $ostream = [System.Io.File]::OpenWrite($outFile)
    $chunkNum = 1
    $infileName = "$infilePrefix$chunkNum"

    $offset = 0

    while(Test-Path $infileName) {
        $bytes = [System.IO.File]::ReadAllBytes($infileName)
        $ostream.Write($bytes, 0, $bytes.Count)
        Write-Host "read $infileName"
        $chunkNum += 1
        $infileName = "$infilePrefix$chunkNum"
    }

    $ostream.close();
}

【讨论】:

    【解决方案3】:

    我回答了 bernd_k 在这个问题的 cmets 中提到的问题,但在这种情况下我会使用 -ReadCount 而不是 -TotalCount,例如

    Get-Content bigfile.bin -ReadCount 100MB -Encoding byte
    

    这会导致Get-Content 在块大小为文本编码的行或字节编码的字节时读取文件的块。请记住,当它执行此操作时,您会得到一个沿管道传递的数组,而不是单个字节或文本行。

    【讨论】:

    • ...对,然后您需要想办法将每个块放入不同的文件中。上面的 Jason Fossen 链接建议不要使用 get-content 操作大型数据集:“get-content 的性能对于大文件来说很糟糕。除非您阅读的内容小于 200KB,否则不要使用 get-content...”你的经验?
    • 另外,您能否将其表达为类似于我上面的完整解决方案?
    • 有机会在一个巨大的文件上尝试这个,是的,除非你有一个 64 位的 PowerShell,否则别管它。 :-) 我在 1KB 的读取计数方面非常幸运,但让 Get-Content 将其打包成 100MB 的块只是无法扩展。可惜 PowerShell 不能更直接地处理这个问题。