Expand-Archive without Importing and Exporting files

家住魔仙堡 提交于 2020-03-04 05:42:19

问题


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

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 only support paths parameters, not objects Is there a better way to handle .zip files?


回答1:


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.

EDIT: 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}
}

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)



回答2:


Although Expand-Archive doesn't accept objects, you can provide it the string property of the objects. E.G. $File.FullName will be a String.

Get-ChildItem C:\temp\ -Filter "*.zip" | 
    ForEach-Object {
        Expand-Archive -Path $_.FullName -DestinationPath "C:\Temp\Extracted\$($_.BaseName)\"
    }


来源:https://stackoverflow.com/questions/59097330/expand-archive-without-importing-and-exporting-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!