无需导入和导出文件即可展开存档 [英] Expand-Archive without Importing and Exporting files

查看:34
本文介绍了无需导入和导出文件即可展开存档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 .zip 文件 (Expand-Archive) 时,如何停止导出然后将文件导入和导出 Powershell?

How do I stop exporting then importing files in and out of Powershell when working with .zip files (Expand-Archive)?

我目前正在使用一个临时文件夹来提取 .zip 文件.是否有一个变量或我遗漏的东西比下面的解决方案更有效?

I am currently using a temporary folder to extract the .zip file. Is there a variable or something I missed that would work better than the solution below?

$filename = 'foobar'
$Zip_in_Bytes | Set-Content -Encoding Byte -Path "C:\temp\filename.zip"
Expand-Archive -Path "C:\temp\filename.zip" -DestinationPath "C:\temp\" -Force
[xml]$xml = Get-Content -Path "C:\temp\filename.xml"

Remove-Item "C:\temp\filename.zip"
Remove-Item "C:\temp\filename.xml"

Expand-Archive 只支持路径参数,不支持对象有没有更好的方法来处理 .zip 文件?

Expand-Archive only support paths parameters, not objects Is there a better way to handle .zip files?

推荐答案

使用 System.IO.Compression 你可以使用字节数组和流而不是临时文件,但它比Expand-Archive.

Using System.IO.Compression you can work with byte arrays and streams rather than temporary files, but it's a bit more work than Expand-Archive.

添加了 Get-ZipEntryContentAdd-ZipEntry 示例调用,并调整了使 $ZipFilePath 成为可选参数的参数.

Added Get-ZipEntryContent and Add-ZipEntry sample calls, and tweaked parameters making $ZipFilePath optional.

@( 'System.IO.Compression','System.IO.Compression.FileSystem') | % { [void][System.Reflection.Assembly]::LoadWithPartialName($_) }

function Get-ZipEntryContent(#returns the bytes of the first matching entry 
  [string] $ZipFilePath, #optional - specify a ZipStream or path 
  [IO.Stream] $ZipStream = (New-Object IO.FileStream($ZipFilePath, [IO.FileMode]::Open)),
  [string] $EntryPath){
    $ZipArchive = New-Object IO.Compression.ZipArchive($ZipStream, [IO.Compression.ZipArchiveMode]::Read)
    $buf = New-Object byte[] (0) #return an empty byte array if not found
    $ZipArchive.GetEntry($EntryPath) | ?{$_} | %{ #GetEntry returns first matching entry or null if there is no match
        $buf = New-Object byte[] ($_.Length)
        Write-Verbose "     reading: $($_.Name)"
        $_.Open().Read($buf,0,$buf.Length)
    }
    $ZipArchive.Dispose()
    $ZipStream.Close()
    $ZipStream.Dispose()
    return $buf 
}


function Add-ZipEntry(#Adds an entry to the $ZipStream. Sample call: Add-ZipEntry -ZipFilePath "$PSScriptRoot\temp.zip" -EntryPath Test.xml -Content ([text.encoding]::UTF8.GetBytes("Testing"))
  [string] $ZipFilePath, #optional - specify a ZipStream or path 
  [IO.Stream] $ZipStream = (New-Object IO.FileStream($ZipFilePath, [IO.FileMode]::OpenOrCreate)),
  [string] $EntryPath, 
  [byte[]] $Content, 
  [switch] $OverWrite, #if specified, will not create a second copy of an existing entry 
  [switch] $PassThru ){#return a copy of $ZipStream
    $ZipArchive = New-Object IO.Compression.ZipArchive($ZipStream, [IO.Compression.ZipArchiveMode]::Update, $true)
    $ExistingEntry = $ZipArchive.GetEntry($EntryPath) | ?{$_} 
    If($OverWrite -and $ExistingEntry){
        Write-Verbose "    deleting existing $($ExistingEntry.FullName)"
        $ExistingEntry.Delete()
    }
    $Entry = $ZipArchive.CreateEntry($EntryPath)
    $WriteStream = New-Object System.IO.StreamWriter($Entry.Open())
    $WriteStream.Write($Content,0,$Content.Length)
    $WriteStream.Flush()
    $WriteStream.Dispose()
    $ZipArchive.Dispose()
    If($PassThru){
        $OutStream = New-Object System.IO.MemoryStream
        $ZipStream.Seek(0, 'Begin') | Out-Null
        $ZipStream.CopyTo($OutStream)
    }
    $ZipStream.Close()
    $ZipStream.Dispose()
    If($PassThru){$OutStream}
}

以下示例说明了如何在内存中完全调用 Add-ZipEntryGet-ZipEntryContent 函数:

Here's an example of how you would call Add-ZipEntry and Get-ZipEntryContent functions completely in memory:

$NewZipStream = Add-ZipEntry -ZipStream (New-Object IO.MemoryStream) -EntryPath Test.xml -Content ([text.encoding]::UTF8.GetBytes("<xml><test>1</test>")) -PassThru
$bytes = Get-ZipEntryContent -ZipStream $NewZipStream -EntryPath 'Test.xml'
[text.encoding]::UTF8.GetString($bytes)

这篇关于无需导入和导出文件即可展开存档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆