Можно ли извлечь / прочитать часть файла в zip-файле с помощью powershell? - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть сценарий powershell 4.0, который выполняет различные функции для организации больших zip-файлов во внутренней сети.Это все работает нормально, но я хочу сделать несколько улучшений.Одна вещь, которую я хочу сделать, это извлечь некоторые детали, которые находятся внутри XML-файла внутри ZIP-файлов.

Я проверил это на некоторых небольших ZIP-файлах, извлекая только тот XML, который работал нормально.Я нацеливаюсь на конкретный файл, потому что zip может содержать тысячи файлов, которые могут быть довольно большими.Это отлично работало с моими тестовыми файлами, но когда я расширил тестирование, я понял, что это не особенно оптимально, потому что XML-файлы, которые я читаю, сами могут стать довольно большими (один был ~ 5 ГБ, но потенциально они могут быть больше).Поэтому добавление шага извлечения файла в цепочку создает неприемлемую задержку для процесса, и мне нужно найти альтернативу.

В идеале я бы мог прочитать 3-5 значений из файла XML изнутриZIP без распаковки.Значения всегда относительно ранние в файле, поэтому, возможно, можно просто извлечь первые ~ 100 КБ файла, и я мог бы обработать извлечение как текстовый файл и найти требуемые значения?

Возможно ли это/ более производительный, чем просто распаковка всего файла?

Если я не смогу ускорить процесс, мне придется взглянуть по-другому.У меня есть ограниченный контроль над содержимым файла, поэтому я могу рассмотреть возможность разделения этих деталей на отдельный файл меньшего размера при создании ZIP.Это будет последнее средство, хотя.

1 Ответ

0 голосов
/ 19 сентября 2019

Вы должны быть в состоянии сделать это с классом System.IO.Compression.ZipFile:

# 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"
}
...