我们在Windows上有一个文件夹......很大.我跑了"dir> list.txt".该命令在1.5小时后丢失了响应.输出文件大约为200 MB.它显示至少有280万个文件.我知道情况很愚蠢,但让我们关注问题本身.如果我有这样的文件夹,我该如何将其拆分为一些"可管理"的子文件夹?令人惊讶的是,我提出的所有解决方案都涉及到在某个时刻获取文件夹中的所有文件,这在我的案例中是禁止的.有什么建议?
感谢Keith Hill和Mehrdad.我接受了Keith的回答,因为这正是我想做的事情,但我无法让PS快速完成.
有了Mehrdad的提示,我写了这个小程序.移动280万个文件需要7个多小时.所以最初的dir命令完成了.但不知怎的,它没有回到控制台.
namespace SplitHugeFolder { class Program { static void Main(string[] args) { var destination = args[1]; if (!Directory.Exists(destination)) Directory.CreateDirectory(destination); var di = new DirectoryInfo(args[0]); var batchCount = int.Parse(args[2]); int currentBatch = 0; string targetFolder = GetNewSubfolder(destination); foreach (var fileInfo in di.EnumerateFiles()) { if (currentBatch == batchCount) { Console.WriteLine("New Batch..."); currentBatch = 0; targetFolder = GetNewSubfolder(destination); } var source = fileInfo.FullName; var target = Path.Combine(targetFolder, fileInfo.Name); File.Move(source, target); currentBatch++; } } private static string GetNewSubfolder(string parent) { string newFolder; do { newFolder = Path.Combine(parent, Path.GetRandomFileName()); } while (Directory.Exists(newFolder)); Directory.CreateDirectory(newFolder); return newFolder; } } }
Keith Hill.. 8
我使用Get-ChildItem将我的整个C:驱动器每晚编入索引到c:\ filelist.txt.那是大约580,000个文件,结果文件大小约为60MB.不可否认,我使用的是带有8 GB RAM的Win7 x64.也就是说,您可以尝试这样的事情:
md c:\newdir Get-ChildItem C:\hugedir -r | Foreach -Begin {$i = $j = 0} -Process { if ($i++ % 100000 -eq 0) { $dest = "C:\newdir\dir$j" md $dest $j++ } Move-Item $_ $dest }
关键是以流媒体方式进行移动.也就是说,不要将所有Get-ChildItem结果收集到单个变量中,然后继续.这将需要所有280万个FileInfos同时在内存中.此外,如果您Name
在Get-ChildItem上使用该参数,它将输出一个包含相对于基础目录的文件路径的字符串.即使这样,也许这个尺寸只会压倒你可用的内存.毫无疑问,执行需要很长时间.正确的IIRC,我的索引脚本需要几个小时.
如果它确实有效,你应该c:\newdir\dir0
通过dir28
但最后再次,我还没有测试过这个脚本,所以你的里程可能会有所不同.顺便说一句,这种方法假设你是一个巨大的目录是一个非常平坦的目录.
更新:使用Name
参数几乎是两倍慢,所以不要使用该参数.
我使用Get-ChildItem将我的整个C:驱动器每晚编入索引到c:\ filelist.txt.那是大约580,000个文件,结果文件大小约为60MB.不可否认,我使用的是带有8 GB RAM的Win7 x64.也就是说,您可以尝试这样的事情:
md c:\newdir Get-ChildItem C:\hugedir -r | Foreach -Begin {$i = $j = 0} -Process { if ($i++ % 100000 -eq 0) { $dest = "C:\newdir\dir$j" md $dest $j++ } Move-Item $_ $dest }
关键是以流媒体方式进行移动.也就是说,不要将所有Get-ChildItem结果收集到单个变量中,然后继续.这将需要所有280万个FileInfos同时在内存中.此外,如果您Name
在Get-ChildItem上使用该参数,它将输出一个包含相对于基础目录的文件路径的字符串.即使这样,也许这个尺寸只会压倒你可用的内存.毫无疑问,执行需要很长时间.正确的IIRC,我的索引脚本需要几个小时.
如果它确实有效,你应该c:\newdir\dir0
通过dir28
但最后再次,我还没有测试过这个脚本,所以你的里程可能会有所不同.顺便说一句,这种方法假设你是一个巨大的目录是一个非常平坦的目录.
更新:使用Name
参数几乎是两倍慢,所以不要使用该参数.