You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ZipArchive类删除WAR包内指定路径的特定文件

解决方案

问题根因

原删除函数仅匹配了ZipArchiveEntry的Name属性(仅存储纯文件名,不带包内路径),因此传入完整路径时无法匹配命中,且重名文件会被全部删除。Zip包内文件的完整路径存储在FullName属性中,且Zip规范默认路径不带开头的/,需要先对传入路径做格式化处理再匹配。

1. 改进后的Remove-FilesFromZip函数(支持按路径删除)

function Remove-FilesFromZip {
    param(
        [string]$ZipFile,
        [string]$FileName
    )
    $zip = $null
    $stream = $null
    try {
        [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression') | Out-Null
        $stream = New-Object IO.FileStream($ZipFile, [IO.FileMode]::Open)
        $mode = [IO.Compression.ZipArchiveMode]::Update
        $zip = New-Object IO.Compression.ZipArchive($stream, $mode)

        # 格式化传入路径,适配Zip内部路径规范
        $cleanPath = $FileName.TrimStart('/','\').Replace('\','/')
        # 优先匹配全路径,未匹配到则回退匹配文件名,兼容原有使用习惯
        $targetEntries = $zip.Entries | Where-Object { $_.FullName -eq $cleanPath }
        if ($targetEntries.Count -eq 0) {
            $targetEntries = $zip.Entries | Where-Object { $_.Name -eq $FileName }
        }
        $targetEntries | ForEach-Object { $_.Delete() }

        Write-Host "$FileName 已从 $ZipFile 中删除"
    }
    catch {
        Write-Host "删除 $ZipFile 中的 $FileName 失败,错误信息:$_"
    }
    finally {
        # 统一释放资源,避免资源泄漏
        if ($zip) { $zip.Dispose() }
        if ($stream) { 
            $stream.Close()
            $stream.Dispose()
        }
    }
}

修改点说明

  • 自动清理传入路径开头的分隔符,自动替换反斜杠为正斜杠,适配Zip内部路径格式
  • 优先匹配全路径,匹配不到时回退匹配文件名,兼容原有使用习惯
  • 优化资源释放逻辑,避免未初始化对象报错

2. 优化后的Move-FileToZip函数(自动覆盖旧文件)

无需单独调用删除函数,添加新文件前自动删除对应路径的旧文件,避免重复文件问题:

function Move-FileToZip {
    param(
        $ZipFileName,
        $FileNameInZip,
        $NewFileToAdd
    )
    $zip = $null
    try {
        [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null
        $zip = [System.IO.Compression.ZipFile]::Open($ZipFileName, "Update")

        # 先删除对应路径的旧文件,实现自动覆盖
        $cleanPath = $FileNameInZip.TrimStart('/','\').Replace('\','/')
        $oldEntry = $zip.GetEntry($cleanPath)
        if ($oldEntry) { $oldEntry.Delete() }

        [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $NewFileToAdd, $cleanPath, "Optimal") | Out-Null
        Write-Host "已成功将 $NewFileToAdd 添加到 $ZipFileName 的 $FileNameInZip 路径"
    }
    catch {
        Write-Host "添加 $NewFileToAdd 到 $ZipFileName 失败,错误信息:$_"
    }
    finally {
        if ($zip) { $zip.Dispose() }
    }
}

使用示例

按指定路径删除文件

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

导入文件自动覆盖旧版本

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

内容的提问来源于stack exchange,提问作者Cezar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:15:09