以下是该方案:
我有一个包含2百多万个文件的目录。我下面的代码在大约90分钟内写出所有文件。有没有人有办法加快速度或使这段代码更有效率?我还想在列表中写出文件名。
string lines = (listBox1.Items.ToString());
string sourcefolder1 = textBox1.Text;
string destinationfolder = (@"C:\anfiles");
using (StreamWriter output = new StreamWriter(destinationfolder + "\\" + "MasterANN.txt"))
{
string[] files = Directory.GetFiles(textBox1.Text, "*.txt");
foreach (string file in files)
{
FileInfo file_info = new FileInfo(file);
output.WriteLine(file_info.Name);
}
}
减速是它一次写出1行。
需要大约13-15分钟才能获得所需的所有文件。
以下75分钟正在创建文件。
答案 0 :(得分:8)
如果您没有为每个文件创建一个FileInfo实例,可能会有所帮助,请使用Path.GetFileName:
string lines = (listBox1.Items.ToString());
string sourcefolder1 = textBox1.Text;
string destinationfolder = (@"C:\anfiles");
using (StreamWriter output = new StreamWriter(Path.Combine(destinationfolder, "MasterANN.txt"))
{
string[] files = Directory.GetFiles(textBox1.Text, "*.txt");
foreach (string file in files)
{
output.WriteLine(Path.GetFileName(file));
}
}
答案 1 :(得分:6)
您正在将超过200万个文件描述符读入内存。根据您拥有的内存量,您可能需要进行交换。尝试通过过滤文件名将其分解为更小的块。
答案 2 :(得分:5)
我需要知道的第一件事是减速在哪里? Directory.GetFiles()需要89分钟才能执行,还是延迟分散到FileInfo file_info = new FileInfo(file);
的调用?
如果延迟来自后者,您可以通过从路径获取文件名而不是创建FileInfo实例来获取文件名来加快速度。
System.IO.Path.GetFileName(file);
答案 3 :(得分:3)
根据我的经验,Directory.GetFiles
会减慢你的速度(除了控制台输出)。要解决这个问题,请将P / Invoke转换为FindFirstFile / FindNextFile以避免所有内存消耗和一般性的延迟。
答案 4 :(得分:0)
使用Directory.EnumerateFiles不需要先将所有文件名加载到内存中。看看这个:C# directory.getfiles memory help
在您的情况下,代码可以是:
using (StreamWriter output = new StreamWriter(destinationfolder + "\\" + "MasterANN.txt"))
{
foreach (var file in Directory.EnumerateFiles(sourcefolder, "*.txt"))
{
output.WriteLine(Path.GetFileName(file));
}
}
来自this doc,它说:
EnumerateFiles和GetFiles方法的不同之处如下:使用EnumerateFiles时,可以在返回整个集合之前开始枚举名称集合;当您使用GetFiles时,您必须等待返回整个名称数组,然后才能访问该数组。因此,当您使用许多文件和目录时,EnumerateFiles可以更有效。
因此,如果您有足够的内存,Directory.GetFiles就可以了。但是当一个文件夹包含数百万个文件时,Directory.EnumerateFiles要好得多。