是否可以使用 powershell 提取/读取 zip 文件的一部分?

Is it possible to extract / read part of a file within a zip using powershell?

我有一个 powershell 4.0 脚本,它执行各种操作来跨内部网络组织一些大型 zip 文件。这一切都很好,但我希望做出一些改进。我想做的一件事是提取 ZIP 文件中 XML 文件中的一些详细信息。

我通过仅提取工作正常的 XML 对一些小 ZIP 文件进行了测试。我以特定文件为目标,因为 zip 可以包含数千个非常大的文件。这在我的测试文件上运行良好,但是当我扩展测试时,我意识到这并不是特别理想,因为我正在阅读的 XML 文件本身可能会变得非常大(一个大约 5GB,但它们可能会更大).因此,在链中添加文件提取步骤会对流程造成不可接受的延迟,我需要找到一个替代方案。

理想情况下,我无需解压缩即可从 ZIP 文件中读取 XML 文件中的 3-5 个值。这些值总是在文件中相对较早的位置,所以也许可以只提取文件的前 ~100kb,我可以将提取物视为文本文件并找到所需的值?

这是否可能/比仅提取整个文件更高效?

如果我不能加快速度,我将不得不考虑另一种方式。我对文件内容的控制有限,因此可能会考虑在创建 ZIP 时将这些细节拆分成一个较小的单独文件。这将是最后的手段。

您应该可以使用 System.IO.Compression.ZipFile class:

# import the containing assembly
Add-Type -AssemblyName System.IO.Compression.FileSystem

try{
  # open the zip file with ZipFile
  $zipFileItem = Get-Item .\Path\To\File.zip
  $zipFile = [System.IO.Compression.ZipFile]::OpenRead($zipFileItem.FullName)

  # find the desired file entry
  $compressedFileEntry = $zipFile.Entries |Where-Object Name -eq MyAwesomeButHugeFile.xml

  # read the first 100kb of the file stream:
  $buffer = [byte[]]::new(100KB)
  $stream = $compressedFileEntry.Open()
  $readLength = $stream.Read($buffer, 0, $buffer.Length)
}
finally{
  # clean up
  if($stream){ $stream.Dispose() }
  if($zipFile){ $zipFile.Dispose() }
}

if($readLength){
  $xmlString = [System.Text.Encoding]::UTF8.GetString($buffer, 0, $readLength)
  # do what you must with `$xmlString` here :)
}
else{
  Write-Warning "Failed to extract partial xml string"
}