在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候會需要加載大批量的文件,而且可能還會存在部分文件缺失的情況,那么如何才能快速判斷文件是否存在呢?如果處理不當,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程序的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否存在的方式以及效率比較。
涉及知識點
- 單個文件是否存在判斷,通常采用File.Exists(file)來判斷文件是否存在,存在返回true,不存在返回false。
- 獲取目錄下的文件,通常采用Directory.GetFiles(dir)來獲取目錄下的文件,返回目錄下的文件列表。
- 計算程序執行耗時,通常采用Stopwatch進行計算,單位可以是毫秒,秒,TimeSpan等。
前提
本示例的前提是,通常有多個文件(如:幾十,幾百,幾千,幾萬)需要判斷是否存在,且文件隸屬于多個目錄。循環文件判斷
C#默認提供的文件存在判斷方式,一般用于單個文件。如果有多個文件,可以批量循環進行判斷。步驟如下:
/// <summary>
/// 逐一判斷是否存在,并返回判斷時長
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
private static long CheckFileExist01(List<string> files)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
foreach (var file in files)
{
if (File.Exists(file))
{
}
}
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
上述判斷方式,如果有一百個文件,則會進行一百次的文件是否存在判斷,都是磁盤文件判斷。
統一獲取判斷
統一獲取,即獲取文件夾目錄下的文件,在內存中判斷文件是否存在。步驟如下:
先獲取文件列表所在的文件夾,
獲取文件夾中的所有文件,存入字典中,
然后通過字典判斷是否包含文件
代碼如下所示:
/// <summary>
/// 統一獲取文件夾目錄中的文件,再進行判斷
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
private static long CheckFileExist02(List<string> files)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Dictionary<string,string> dictionary = new Dictionary<string, string>();
var folders = files.Select(item=>Path.GetDirectoryName(item)).Distinct().ToList();
foreach (var folder in folders)
{
var tmpFiles=Directory.GetFiles(folder);
foreach(var tmpFile in tmpFiles)
{
dictionary[tmpFile] = tmpFile;
}
}
foreach (var file in files)
{
if (dictionary.TryGetValue(file, out string a))
{
}
}
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
性能比較
在本示例中,分別從不同維度進行比較,如:本地文件和共享目錄文件,以及不同文件數量進行比較。分別如下:本地文件,分別對10到500個文件進行判斷是否存在,對兩種方式的耗時比較。
其中橫坐標為文件數量,縱坐標為判斷文件是否存在的執行耗時(毫秒)。如下所示:- 對于需要判斷的文件數量較少時,循環單個文件和統一獲取再判斷,性能上并無太大差異。
- 隨著需要判斷的文件數量逐漸增多,循環單個文件的耗時會增加,而統一獲取在內存判斷,則并無太大波動。
2. 共享目錄文件
共享文件,分別對10到500個文件進行判斷是否存在,對兩種方式的耗時比較。
其中橫坐標為文件數量,縱坐標為判斷文件是否存在的執行耗時(毫秒)。如下所示:- 隨著需要判斷的文件數量逐漸增多,循環單個文件的耗時會增加,而統一獲取在內存判斷,則并無太大波動。
結論
通過對本地文件和共享目錄下文件,以及不同數量的文件進行文件是否存在校驗的耗時比較分析,結論如下:
如果需要判斷的文件數量比較多,且分散存儲的目錄雖然不唯一,卻相對集中,建議采用第二種(統一獲取)方式進行校驗。
該文章在 2024/7/22 12:34:40 編輯過