使用 Compress-Archive 压缩与 Powershell 多线程的多个文件夹
Using Compress-Archive to compress multiple folders multithreadded with Powershell
每天我都需要创建以下内容的档案
C:.
└───1.Jan
├───20000
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20001
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20002
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20003
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20004
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20005
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
└───Entered
我目前使用脚本一次创建一个 zip 文件,但是有时我可以压缩 200 多个文件夹,而且它们的大小不同,所以我想让这个工作多线程。
function Zip-Folders([String] $FolderPath) {
if ($FolderPath -eq '') {
return
}
else {
$FolderNames = Get-ChildItem -Path $FolderPath -Name -Directory -Exclude Enter*
foreach ($i in $FolderNames) {
$TempPath = "$FolderPath$i"
$TempFileName = "$i Photos"
if (-Not(Get-ChildItem -Path $TempPath | Where-Object {$_.Name -like '*.zip'})) {
Write-Host "[$TempPath] has been compressed to [$TempFileName]."
Compress-Archive -Path $tempPath\* -DestinationPath $tempPath$TempFileName
}
Else {
Write-Host "[$i] has already been compressed."
}
}
}
}
代码通过文件夹浏览器对话框请求文件夹。
如果有人可以帮助我编写代码或指出我可以找到相关信息的方向,我是 PowerShell 的初学者,但已经完成了一些编程工作。
如果需要任何其他信息,请告诉我。
这是使用 Runspace
的方法,使用 -Threshold
参数取决于您要同时压缩的文件夹数量。
如评论所述,如果您有能力在您的环境中安装模块,强烈建议使用 ThreadJob
Module。
function Zip-Folders {
[cmdletbinding()]
param(
[ValidateScript({ Test-Path $_ -PathType Container })]
[Parameter(Mandatory)]
[String] $FolderPath,
[int] $Threshold = 10
)
begin {
$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $Threshold)
$RunspacePool.Open()
$subFolders = Get-ChildItem -Path $FolderPath -Directory -Exclude Enter*
}
process {
try {
$runspaces = foreach ($folder in $subFolders) {
$instance = [powershell]::Create().AddScript({
param($thisFolder)
$fileName = "{0} Photos.zip" -f $thisFolder.Name
$absolutePath = $thisFolder.FullName
$zipPath = Join-Path $absolutePath -ChildPath $fileName
if(-not (Get-ChildItem -Path $absolutePath -Filter *.zip)) {
Compress-Archive -Path $absolutePath\* -DestinationPath $zipPath
return "[$absolutePath] has been compressed to [$zipPath]."
}
"[$absolutePath] has already been compressed."
}).AddParameter('thisFolder', $folder)
$instance.RunspacePool = $RunspacePool
[pscustomobject]@{
Instance = $instance
Handle = $instance.BeginInvoke()
}
}
foreach($r in $runspaces) {
$r.Instance.EndInvoke($r.Handle)
$r.Instance.ForEach('Dispose')
}
}
catch {
$PSCmdlet.WriteError($_)
}
finally {
$runspaces.ForEach('Clear')
$RunspacePool.ForEach('Dispose')
}
}
}
每天我都需要创建以下内容的档案
C:.
└───1.Jan
├───20000
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20001
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20002
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20003
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20004
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
├───20005
│ img1.bmp
│ img2.bmp
│ img3.bmp
│
└───Entered
我目前使用脚本一次创建一个 zip 文件,但是有时我可以压缩 200 多个文件夹,而且它们的大小不同,所以我想让这个工作多线程。
function Zip-Folders([String] $FolderPath) {
if ($FolderPath -eq '') {
return
}
else {
$FolderNames = Get-ChildItem -Path $FolderPath -Name -Directory -Exclude Enter*
foreach ($i in $FolderNames) {
$TempPath = "$FolderPath$i"
$TempFileName = "$i Photos"
if (-Not(Get-ChildItem -Path $TempPath | Where-Object {$_.Name -like '*.zip'})) {
Write-Host "[$TempPath] has been compressed to [$TempFileName]."
Compress-Archive -Path $tempPath\* -DestinationPath $tempPath$TempFileName
}
Else {
Write-Host "[$i] has already been compressed."
}
}
}
}
代码通过文件夹浏览器对话框请求文件夹。
如果有人可以帮助我编写代码或指出我可以找到相关信息的方向,我是 PowerShell 的初学者,但已经完成了一些编程工作。
如果需要任何其他信息,请告诉我。
这是使用 Runspace
的方法,使用 -Threshold
参数取决于您要同时压缩的文件夹数量。
如评论所述,如果您有能力在您的环境中安装模块,强烈建议使用 ThreadJob
Module。
function Zip-Folders {
[cmdletbinding()]
param(
[ValidateScript({ Test-Path $_ -PathType Container })]
[Parameter(Mandatory)]
[String] $FolderPath,
[int] $Threshold = 10
)
begin {
$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $Threshold)
$RunspacePool.Open()
$subFolders = Get-ChildItem -Path $FolderPath -Directory -Exclude Enter*
}
process {
try {
$runspaces = foreach ($folder in $subFolders) {
$instance = [powershell]::Create().AddScript({
param($thisFolder)
$fileName = "{0} Photos.zip" -f $thisFolder.Name
$absolutePath = $thisFolder.FullName
$zipPath = Join-Path $absolutePath -ChildPath $fileName
if(-not (Get-ChildItem -Path $absolutePath -Filter *.zip)) {
Compress-Archive -Path $absolutePath\* -DestinationPath $zipPath
return "[$absolutePath] has been compressed to [$zipPath]."
}
"[$absolutePath] has already been compressed."
}).AddParameter('thisFolder', $folder)
$instance.RunspacePool = $RunspacePool
[pscustomobject]@{
Instance = $instance
Handle = $instance.BeginInvoke()
}
}
foreach($r in $runspaces) {
$r.Instance.EndInvoke($r.Handle)
$r.Instance.ForEach('Dispose')
}
}
catch {
$PSCmdlet.WriteError($_)
}
finally {
$runspaces.ForEach('Clear')
$RunspacePool.ForEach('Dispose')
}
}
}