【问题标题】:Zip high volume of folders & files压缩大量文件夹和文件
【发布时间】:2014-06-14 01:06:00
【问题描述】:

我在备份一个包含大量 (10 000 000 +) 个小文件的共享时遇到了很大的问题。据我所知,这些文件的总兆字节不是那么大,但最大的问题是文件数量。

首先要做的事情: - 共享或多或少是“常规”,因此有一个根目录,其中包含 30 个目录。所有这些第一级目录都包含日期格式为:yyMMdd 的子文件夹。

我创建了一些 PowerShell 脚本来根据名称中的日期压缩这些目录,所以,现在,我只在 .zip 文件上运行备份,但是...

我观察到脚本运行时间每天都在增加(因为这个脚本仍然需要检查所有文件夹)。而且文件夹的数量每天都在增加

我的问题是: 是否有任何 - 比方说 - 标记以这种方式使用它: - 当脚本运行并将目录添加到存档时,将今天的文件夹标记为“已存档”,以便在下次脚本运行时跳过那些已经存档的文件夹。

这将给我每天或多或少相同的脚本运行时间,因为它将或多或少地“检查和归档”尚未归档的目录数量。

谁能给点建议?任何想法?我现在没有办法了。

脚本不是很复杂:

$zip = "C:\apps\7-zip\7z.exe"
$days_behind = -1
$folder_data = (Get-Date).AddDays($days_behind).ToString("yyMMdd")
$archive = "X:\SHARE_ARCH\Archive_$folder_data.zip"
$to_zip = (gci X:\SHARE_ROOT -Recurse | ?{ $_.PSIsContainer } | ?{$_.Name -contains ($folder_data)}).FullName
$options = "a", "-tzip", "-y", $archive, $to_zip;
$zip $options;

我认为最有问题的是这一行:

$to_zip = (gci X:\SHARE_ROOT -Recurse | ?{ $.PSIsContainer } | ?{$.Name -contains ($folder_data)}).FullName

【问题讨论】:

  • 您的脚本是什么样的,您如何检查文件夹以及检查什么?给我们看代码
  • 添加到原帖
  • 你运行的是什么版本的powershell?
  • 谢谢大家,我重新设计了“搜索查询”,现在它可以按我的意愿工作了。
  • 您是否尝试过@TheMadTechnician 或我的解决方案(如果是,哪个更快)?

标签: powershell backup archive


【解决方案1】:

好的,如果您有 PSv3 或更高版本,您可以删除 $_.PSIsContainer -and,而是将 -Directory 添加到 GCI 命令中,这将有助于通过在提供程序级别而不是之后进行过滤来加速它。

这将阻止它递归所有内容,并且只会拉取根文件夹中的所有文件夹,并检查它们是否有一个带有所需名称的子文件夹。这应该会大大加快速度。

$zip = "C:\apps\7-zip\7z.exe"
$days_behind = -1
$folder_data = (Get-Date).AddDays($days_behind).ToString("yyMMdd")
$archive = "X:\SHARE_ARCH\Archive_$folder_data.zip"
$to_zip = gci X:\SHARE_ROOT | ?{ $_.PSIsContainer -and (test-path "$_\$folder_data")} | Select -Expand FullName
$options = "a", "-tzip", "-y", $archive, $to_zip
& $zip $options

我还删除了括号并改用Select -expand 命令。我不知道它是否真的会改变速度,但总的来说它更干净。

【讨论】:

    【解决方案2】:

    这将消除第二个 where 应该加快速度的语句:

    $to_zip = (gci X:\SHARE_ROOT -Recurse -Include ("*" + $folder_data + "*") |  ?{ $_.PSIsContainer }
    

    根据@TheMadTechnician,如果你有 PS3+,你可以使用 -Directory 开关和 gci 来进一步加快速度。一个稍微偏左的方法是使用旧的命令提示符获取目录列表并在 Powershell 中处理它们 - 更快!试试这个:

    $to_zip = (cmd /c "dir X:\SHARE_ROOT /A:D /S /B | findstr /i $folder_data") -split "`n"
    

    让我知道你过得怎么样。

    【讨论】: