有没有办法停止 Directory.GetFiles 搜索
Is there a way to stop a Directory.GetFiles search
我正在使用 Directory.GetFiles()
在多文件夹目录中搜索文件,其中一些文件夹太大,因此搜索可能需要长达 60 秒的时间。在下面的代码中,搜索在用户停止输入后一秒钟开始,当用户输入文件名并且在输入时不暂停时,这非常有效,但如果 he/she 在单词中间暂停,搜索将开始即使 he/she 再次开始输入,它也不会停止直到完成。
我想做的是在用户输入时停止搜索,可能在 inputFileName_TextChanged 方法中。
有没有办法停止使用 Directory.GetFiles
时已经开始的搜索?
using System.Timers;
using System.IO;
namespace findFileTest
{
public partial class MainWindow : Window
{
Timer timer = new Timer();
public MainWindow()
{
InitializeComponent();
timer.Elapsed += new ElapsedEventHandler(TimerEvent);
timer.Interval = 1000;
timer.Enabled = true;
timer.Stop();
}
private void inputFileName_TextChanged(object sender, TextChangedEventArgs e)
{
// How to stop the search currently in process here
timer.Stop();
timer.Start();
}
public void TimerEvent(object source, ElapsedEventArgs e)
{
timer.Stop();
findFile();
}
private void findFile()
{
string fName = "";
this.Dispatcher.Invoke(() => {
fName = inputFileName.Text;
});
var fType = ".txt";
var fileName = fName.Trim() + fType;
var file = Directory.GetFiles(@"C:\TestFolder\", fileName, SearchOption.AllDirectories).FirstOrDefault();
if (file == null) {
Console.WriteLine("File not found");
}
else {
Console.WriteLine("Found:" + file);
}
}
}
}
Is there a way to stop a search that has been already started when using Directory.GetFiles?
不,不安全。 GetFiles()
方法不提供任何机制来中断其在 return 之前的工作。您将不得不中止该线程,这会导致许多其他问题。
如 中所述,从字面上理解您的请求,答案是使用 Directory.EnumerateFiles()
方法。此方法通过提供一次 return 一个文件的枚举器来显示底层 FindFirstFile()
和 FindNextFile()
的语义。每次 returned 新文件时,您都有机会中断枚举和 return 而无需做更多工作。
请注意,即使使用 EnumerateFiles()
,您也不会获得第一个文件结果,直到它找到与您的搜索模式匹配的内容。如果您切换到使用 EnumerateFiles()
,您很可能还想对输入进行自己的匹配,而不是让 EnumerateFiles()
进行。 IE。将 "*"
作为搜索字符串传递。这会稍微减慢整体操作速度,但您将有机会中断搜索目录和子目录中的 每个 文件的操作,而不是仅在找到匹配文件时才中断.
最后,我建议您根据明显的用例,重新考虑使用 Directory
class。根据您发布的代码,每次用户输入一些新文本时,您都会开始搜索文件系统,这必然是一个缓慢的操作。恕我直言,最好建立一次索引(例如 Dictionary<string, List<string>>
将不带扩展名的文件名(即 Path.GetFileNameWithoutExtension()
映射到目录中每个匹配文件的完整路径)。这样,您就不必打断任何事情。用户输入文本后的 "search" 部分几乎是即时的。
在目录被完全索引之前当然会有一个初始延迟。这取决于你想如何处理它。但我建议提供一种机制,既可以向用户表明索引编制尚未完全完成,又可以检查您拥有的内容,以防万一用户查找的文件与已编制索引的文件相匹配。
请注意,通常使用的 Windows 文件系统 — FAT、FAT32、NTFS 等 — 不区分大小写,因此您需要使用 StringComparer.OrdinalIgnoreCase
初始化字典。 "Ordinal",因为文件系统名称需要与用户键入的字符完全匹配,"ignore case" 以便搜索不区分大小写。
我猜想在您的场景中,当用户使用您的程序搜索文件时不太可能添加或删除文件。但是,如果您担心这种情况,您可以只为用户提供一个 "Refresh" 按钮来强制目录重新编制索引,或者使用 FileSystemWatcher
在添加文件时自动更新索引或已删除。
我正在使用 Directory.GetFiles()
在多文件夹目录中搜索文件,其中一些文件夹太大,因此搜索可能需要长达 60 秒的时间。在下面的代码中,搜索在用户停止输入后一秒钟开始,当用户输入文件名并且在输入时不暂停时,这非常有效,但如果 he/she 在单词中间暂停,搜索将开始即使 he/she 再次开始输入,它也不会停止直到完成。
我想做的是在用户输入时停止搜索,可能在 inputFileName_TextChanged 方法中。
有没有办法停止使用 Directory.GetFiles
时已经开始的搜索?
using System.Timers;
using System.IO;
namespace findFileTest
{
public partial class MainWindow : Window
{
Timer timer = new Timer();
public MainWindow()
{
InitializeComponent();
timer.Elapsed += new ElapsedEventHandler(TimerEvent);
timer.Interval = 1000;
timer.Enabled = true;
timer.Stop();
}
private void inputFileName_TextChanged(object sender, TextChangedEventArgs e)
{
// How to stop the search currently in process here
timer.Stop();
timer.Start();
}
public void TimerEvent(object source, ElapsedEventArgs e)
{
timer.Stop();
findFile();
}
private void findFile()
{
string fName = "";
this.Dispatcher.Invoke(() => {
fName = inputFileName.Text;
});
var fType = ".txt";
var fileName = fName.Trim() + fType;
var file = Directory.GetFiles(@"C:\TestFolder\", fileName, SearchOption.AllDirectories).FirstOrDefault();
if (file == null) {
Console.WriteLine("File not found");
}
else {
Console.WriteLine("Found:" + file);
}
}
}
}
Is there a way to stop a search that has been already started when using Directory.GetFiles?
不,不安全。 GetFiles()
方法不提供任何机制来中断其在 return 之前的工作。您将不得不中止该线程,这会导致许多其他问题。
如 Directory.EnumerateFiles()
方法。此方法通过提供一次 return 一个文件的枚举器来显示底层 FindFirstFile()
和 FindNextFile()
的语义。每次 returned 新文件时,您都有机会中断枚举和 return 而无需做更多工作。
请注意,即使使用 EnumerateFiles()
,您也不会获得第一个文件结果,直到它找到与您的搜索模式匹配的内容。如果您切换到使用 EnumerateFiles()
,您很可能还想对输入进行自己的匹配,而不是让 EnumerateFiles()
进行。 IE。将 "*"
作为搜索字符串传递。这会稍微减慢整体操作速度,但您将有机会中断搜索目录和子目录中的 每个 文件的操作,而不是仅在找到匹配文件时才中断.
最后,我建议您根据明显的用例,重新考虑使用 Directory
class。根据您发布的代码,每次用户输入一些新文本时,您都会开始搜索文件系统,这必然是一个缓慢的操作。恕我直言,最好建立一次索引(例如 Dictionary<string, List<string>>
将不带扩展名的文件名(即 Path.GetFileNameWithoutExtension()
映射到目录中每个匹配文件的完整路径)。这样,您就不必打断任何事情。用户输入文本后的 "search" 部分几乎是即时的。
在目录被完全索引之前当然会有一个初始延迟。这取决于你想如何处理它。但我建议提供一种机制,既可以向用户表明索引编制尚未完全完成,又可以检查您拥有的内容,以防万一用户查找的文件与已编制索引的文件相匹配。
请注意,通常使用的 Windows 文件系统 — FAT、FAT32、NTFS 等 — 不区分大小写,因此您需要使用 StringComparer.OrdinalIgnoreCase
初始化字典。 "Ordinal",因为文件系统名称需要与用户键入的字符完全匹配,"ignore case" 以便搜索不区分大小写。
我猜想在您的场景中,当用户使用您的程序搜索文件时不太可能添加或删除文件。但是,如果您担心这种情况,您可以只为用户提供一个 "Refresh" 按钮来强制目录重新编制索引,或者使用 FileSystemWatcher
在添加文件时自动更新索引或已删除。