最近帮公司运维的同事写了个把多个文件打包成zip的PowerShell脚本,无需第三方程序(如WinRAR)或类库,来跟大家分享下。
其实.Net本身就自带了Zip压缩的类库,只是由于不怎么常用,默认没加载。不管是PowerShell还是c#,只要添加引用WindowsBase.dll就行了。
.Net Framework需要3.0或以上,我在Windows Server 2008 R2+.Net Framework 3.5+PowerShell 2.0下测试通过。
以下是PowerShell脚本:
$EmlPath="d:\sandbox\eml" #文件所在的文件夹
$ZipPath="D:\sandbox\zip\" + (Get-Date).ToString('yyyy-MM-dd hh-mm-ss') + ".zip" #最终输出的Zip文件,以时间动态生成。
#加载依赖
[System.Reflection.Assembly]::Load("WindowsBase,
Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
#删除已有的压缩包
if (Test-Path($ZipPath))
{
Remove-Item $ZipPath
}
#获取文件集合
$Di=New-Object System.IO.DirectoryInfo($EmlPath);
$files = $Di.GetFiles()
if($files.Count -eq 0)
{
exit
}
#打开压缩包
$pkg=[System.IO.Packaging.ZipPackage]::Open($ZipPath,
[System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")
#加入文件到压缩包
ForEach ($file In $files)
{
$uriString="/" +$file.Name
$partName=New-Object System.Uri($uriString, [System.UriKind]"Relative")
$pkgPart=$pkg.CreatePart($partName, "application/zip",
[System.IO.Packaging.CompressionOption]"Maximum")
$bytes=[System.IO.File]::ReadAllBytes($file.FullName)
$stream=$pkgPart.GetStream()
$stream.Seek(0, [System.IO.SeekOrigin]"Begin");
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
Remove-Item $file.FullName
}
#关闭压缩包
$pkg.Close()
既然PowerShell能做到,C#当然也毫无压力:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Packaging;
namespace ConsoleApplicationTest
{
class Program
{
static void Main(string[] args)
{
Zipper zp = new Zipper();
DirectoryInfo di = new DirectoryInfo(@"D:\sandbox\eml");
zp.Create(di.GetFiles(), @"D:\sandbox\zip\" + DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss") + ".zip");
Console.WriteLine("Done.");
Console.Read();
}
}
class Zipper
{
public bool Create(FileInfo[] files, string zipPath)
{
if (System.IO.File.Exists(zipPath))
System.IO.File.Delete(zipPath);
using (Package pkg = ZipPackage.Open(zipPath, FileMode.Create, FileAccess.ReadWrite))
{
foreach (var f in files)
{
try
{
Uri partName = new Uri("/" + f.Name, UriKind.Relative);
PackagePart pp = pkg.CreatePart(partName, "application/zip", CompressionOption.Maximum);
byte[] bytes = System.IO.File.ReadAllBytes(f.FullName);
Stream s = pp.GetStream();
s.Seek(0, SeekOrigin.Begin);
s.Write(bytes, 0, bytes.Length);
s.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
pkg.Close();
return false;
}
}
pkg.Close();
}
return true;
}
}
}
希望对大家有帮助。