Удалите определенные файлы из папки внутри файла войны с помощью класса ZipArchive

#java #powershell #war

Вопрос:

Моя цель-получить некоторые файлы из ВОЙНЫ, внести изменения, удалить старые файлы из ВОЙНЫ, а затем переместить отредактированные файлы в ВОЙНУ.

На данный момент я могу находить, редактировать, удалять и перемещать файлы из файла WAR с помощью класса ZipArchive. Но проблема, с которой я сталкиваюсь, заключается в том, что я не могу удалять файлы из определенных папок внутри ВОЙНЫ, просто по имени.

Учитывая структуру ВОЙНЫ, у меня есть:
~/война
~/war/client/lib/file.jar
~/war/server/lib/file.jar

Пока я не достиг этого момента, я использовал следующую функцию для удаления файлов:

 function Remove-FilesFromZip {  param(  [string]$ZipFile,  [string]$FileName  )   try {    [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression')  $Retorno  $stream = New-Object IO.FileStream($ZipFile, [IO.FileMode]::Open)  $mode = [IO.Compression.ZipArchiveMode]::Update  $zip = New-Object IO.Compression.ZipArchive($stream, $mode)  Write-Host "$zip $mode $stream $Retorno"    ($zip.Entries | Where-Object { $FileName -contains $_.Name }) | ForEach-Object { $_.Delete() }   Write-Host "$FileName excluido de $ZipFile"   }  catch {  Write-Host "Erro ao excluir $FileName de $ZipFile"    $zip.Dispose()  $stream.Close()  $stream.Dispose()  }   $zip.Dispose()  $stream.Close()  $stream.Dispose()  }  

Поскольку файлы, которые я удалял, появлялись только один раз в моей ВОЙНЕ, это не было проблемой, но если я попробую что-то подобное:

 Remove-FilesFromZip "C:/pathToWar/warFile.war" "file.jar"  

Оба файла удалены из войны.

И если я попытаюсь использовать путь таким образом:

 Remove-FilesFromZip "C:/pathToWar/warFile.war" "/server/lib/file.jar"  

Ничего не происходит.

How can I edit my function so I can describe the path to the file I would like to delete ?

Кроме того, для контекста у меня есть еще одна функция, которую я использую после этой, чтобы я мог перемещать файлы в war и в нужную папку, но когда я перемещаюсь, не удаляя файл с тем же именем, у меня внутри есть дубликаты файлов, и это нежелательно.

Это и есть функция:

 function Move-FileToZip {  param(  $ZipFileName,  $FileNameInZip,  $NewFileToAdd  )  try {  # Write-LogWIthTime "-------------- Move-FileToZip --------------"   [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null  $zip = [System.IO.Compression.ZipFile]::Open($ZIPFileName, "Update")   [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null  [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $NewFileToAdd, $FileNameInZip, "Optimal") | Out-Null  $zip.Dispose()   Write-Host "Adicionado com sucesso $NewFileToAdd as $FileNameInZip para $ZIPFileName "  }  catch {  $zip.Dispose()  Write-Host "Falha ao adicionar $NewFileToAdd para $ZIPFileName . Detalhes : $_"   } }  

Которые я использую в качестве:

 Move-FileToZip "C:/pathToWar/warFile.war" "/server/lib/file.jar" "C:/updatedFiles/server/lib/file.jar"  

Идеальным сценарием для меня было бы просто обновить файл, когда я использую функцию Move-FileToZip, но просто заставить файл Remove-FilesFromZip работать так, как я намереваюсь, было бы здорово!

Комментарии:

1. Поскольку ВОЙНА-это всего лишь zip-архив, почему бы не извлечь его, не сделать что угодно и не перезаписать? Может быть, у людей с Java есть идеи получше?

Ответ №1:

Проблема с вашей Remove-FilesFromZip функцией заключается в том, что вы фильтруете записи Zip с помощью Name свойства, и поэтому вы не можете различать файлы с одинаковым именем, но в разных каталогах.

 $zip.Entries | Where-Object { $FileName -contains $_.Name }  

Если вместо этого вы отфильтруете с помощью FullName свойства, вы сможете выбрать конкретный файл, используя его полное имя в zip-файле:

 $zip.Entries | Where-Object { $FileName -eq $_.FullName }  

С этим изменением вы должны быть в состоянии сделать что-то вроде следующего, предполагая, что client это каталог верхнего уровня в zip-файле:

 Remove-FilesFromZip "C:/pathToWar/warFile.war" "client/lib/file.jar"  

Комментарии:

1. Это сработало, используя собственность FullName . Как новичок в powershell, я не задумывался о свойствах $_ . Спасибо @don-cruickshank за ваше время.