【问题标题】:How to read contents of a csv file inside zip file using PowerShell如何使用 PowerShell 读取 zip 文件中的 csv 文件内容
【发布时间】:2016-09-30 09:31:19
【问题描述】:

我有一个 zip 文件,其中包含多个 CSV 文件。如何在不使用 PowerShell 提取 zip 文件的情况下读取这些 CSV 文件的内容?

我一直在使用 Read-Archive Cmdlet,它包含在 PowerShell Community Extensions (PSCX)

这是我迄今为止尝试过的。

$path = "$env:USERPROFILE\Downloads\"
$fullpath = Join-Path $path filename.zip

Read-Archive $fullpath | Foreach-Object {
    Get-Content $_.Name
}

但是当我运行代码时,我收到了这个错误信息 Get-Content : 指定路径 filename.csv 处的对象不存在,或已被 -Include 或 -Exclude 参数过滤。

但是,当我运行 Read-Archive $fullpath 时,它会列出 zip 文件中的所有文件

【问题讨论】:

    标签: csv powershell zip archive


    【解决方案1】:

    有多种方法可以实现:

    1.这是一个使用 Ionic.zip dll 的示例:

    clear
    Add-Type -Path "E:\sw\NuGet\Packages\DotNetZip.1.9.7\lib\net20\Ionic.Zip.dll"
    $zip = [Ionic.Zip.ZipFile]::Read("E:\E.zip")
    
    $file = $zip | where-object { $_.FileName -eq "XMLSchema1.xsd"}
    
    $stream = new-object IO.MemoryStream
    $file.Extract($stream)
    $stream.Position = 0
    
    $reader = New-Object IO.StreamReader($stream)
    $text = $reader.ReadToEnd()
    $text
    
    $reader.Close()
    $stream.Close()
    $zip.Dispose()
    

    它按名称 (XMLSchema1.xsd) 选择文件并将其提取到内存流中。然后,您需要将内存流读入您喜欢的内容(在我的示例中为字符串)。

    2。在 Powershell 5 中,您可以使用 Expand-Archive,请参阅:https://technet.microsoft.com/en-us/library/dn841359.aspx?f=255&MSPPError=-2147217396

    它会将整个存档提取到一个文件夹中:

    Expand-Archive "E:\E.zip" "e:\t"
    

    请记住,提取整个存档需要时间,然后您必须清理临时文件

    3.还有一种只提取 1 个文件的方法:

    $shell = new-object -com shell.application
    $zip = $shell.NameSpace("E:\E.zip")
    $file =  $zip.items() | Where-Object { $_.Name -eq "XMLSchema1.xsd"}
    $shell.Namespace("E:\t").copyhere($file)
    

    4.还有一种使用原生方式的方法:

    Add-Type -assembly "system.io.compression.filesystem"
    $zip = [io.compression.zipfile]::OpenRead("e:\E.zip")
    $file = $zip.Entries | where-object { $_.Name -eq "XMLSchema1.xsd"}
    $stream = $file.Open()
    
    $reader = New-Object IO.StreamReader($stream)
    $text = $reader.ReadToEnd()
    $text
    
    $reader.Close()
    $stream.Close()
    $zip.Dispose()
    

    【讨论】:

    • 这需要安装第三方 dll。宁愿没有。
    • 没错,但您仍然在使用扩展程序,安装 dll 有点困难
    • 我想要一个不需要解压缩 zip 的解决方案。还更新了我的问题以提及这一点。
    • 您的更新仍然需要将 zip 文件中的所有文件解压缩到一个文件夹中
    • 获取 您不能在空值表达式上调用方法。 for $stream = $file.Open()
    【解决方案2】:

    基于Andrey的4.解决方案,我提出如下函数:

    (请记住,“ZipFile”类从 .NET Framework 4.5 开始就存在)

    Add-Type -assembly "System.IO.Compression.FileSystem"
    
    function Read-FileInZip($ZipFilePath, $FilePathInZip) {
        try {
            if (![System.IO.File]::Exists($ZipFilePath)) {
                throw "Zip file ""$ZipFilePath"" not found."
            }
    
            $Zip = [System.IO.Compression.ZipFile]::OpenRead($ZipFilePath)
            $ZipEntries = [array]($Zip.Entries | where-object {
                    return $_.FullName -eq $FilePathInZip
                });
            if (!$ZipEntries -or $ZipEntries.Length -lt 1) {
                throw "File ""$FilePathInZip"" couldn't be found in zip ""$ZipFilePath""."
            }
            if (!$ZipEntries -or $ZipEntries.Length -gt 1) {
                throw "More than one file ""$FilePathInZip"" found in zip ""$ZipFilePath""."
            }
    
            $ZipStream = $ZipEntries[0].Open()
    
            $Reader = [System.IO.StreamReader]::new($ZipStream)
            return $Reader.ReadToEnd()
        }
        finally {
            if ($Reader) { $Reader.Dispose() }
            if ($Zip) { $Zip.Dispose() }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多