例如:
start > ReadFiles(C:\music\);
ReadFiles(path){
foreach(file)
save to index;
foreach(directory)
ReadFiles(directory);
}
这个程序可以正常运行,但是在运行过程中使用的内存量会不断增加,最终导致系统内存耗尽。
有没有更好的方法来完成这个任务,而不需要4GB的RAM?
祝好,Tys
start > ReadFiles(C:\music\);
ReadFiles(path){
foreach(file)
save to index;
foreach(directory)
ReadFiles(directory);
}
这个程序可以正常运行,但是在运行过程中使用的内存量会不断增加,最终导致系统内存耗尽。
有没有更好的方法来完成这个任务,而不需要4GB的RAM?
祝好,Tys
Alxandr的基于队列的解决方案应该可以正常工作。
如果你在使用.NET 4.0,你还可以利用新的Directory.EnumerateFiles
方法,它会懒惰枚举文件,而不会将它们全部加载到内存中:
void ReadFiles(string path)
{
IEnumerable<string> files =
Directory.EnumerateFiles(
path,
"*",
SearchOption.AllDirectories); // search recursively
foreach(string file in files)
SaveToIndex(file);
}
你有检查过除根目录外的每个目录中都会出现的.
和..
条目吗?
如果你没有跳过它们,那么你将会陷入无限循环。
Directory.GetFiles
也不出现在Directory.GetDirectories
中。通常情况下,在.NET中工作时不应遇到此问题。 - configurator你可以将其实现为队列。我认为(但我不确定)这将节省内存。至少它会释放你的堆栈。每当你找到一个文件夹时,就把它添加到队列中,每当你找到一个文件时,就读取它。这可以避免递归。
类似这样:
Queue<string> dirs = new Queue<string>();
dirs.Enqueue("basedir");
while(dirs.Count > 0) {
foreach(directory)
dirs.Enqueue(directory);
ReadFiles();
}
这可能是由于连接文件夹导致递归时出现无限循环,但我不确定,请自行检查。链接:https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/mklink
注意,如果您无法访问文件,路径太长或发生其他异常,EnumerateFiles() 将停止运行。目前我使用以下方法来解决这些问题:
public static List<string> getFiles(string path, List<string> files)
{
IEnumerable<string> fileInfo = null;
IEnumerable<string> folderInfo = null;
try
{
fileInfo = Directory.EnumerateFiles(str);
}
catch
{
}
if (fileInfo != null)
{
files.AddRange(fileInfo);
//recurse through the subfolders
fileInfo = Directory.EnumerateDirectories(str);
foreach (string s in folderInfo)
{
try
{
getFiles(s, files);
}
catch
{
}
}
}
return files;
}
使用示例:
List<string> files = new List<string>();
files = folder.getFiles(path, files);
我的解决方案基于此页面上的代码:http://msdn.microsoft.com/en-us/library/vstudio/bb513869.aspx。
更新:可以在http://social.msdn.microsoft.com/Forums/vstudio/en-US/ae61e5a6-97f9-4eaa-9f1a-856541c6dcce/directorygetfiles-gives-me-access-denied?forum=csharpgeneral找到一个更快的递归获取文件的方法。使用Stack对我来说是新的(我甚至不知道它的存在),但这种方法似乎有效。至少它列出了我C和D分区上的所有文件,没有错误。