通过多个文件夹返回文件列表的最有效方法
本文关键字:列表 有效 方法 文件 返回 文件夹 | 更新日期: 2023-09-27 18:04:30
嗨,我有下面的代码,当符合某些条件时,它将从路由目录中获取所有文件,包括子目录。目前我有两种方法;一种方法是获取所有文件并将其添加到列表中,然后另一种方法返回列表。只是想知道这是最好的方法,还是将两者结合起来更有效?或者可以重写我的代码以提高效率吗?对不起,我对这一切还很陌生!
public class FileUtility
{
List<FileInfo> fileInfoList = new List<FileInfo>();
public void ProcessDir(string sourceDir, String userName)
{
try
{
string userNameFirstLetter = userName.First().ToString();
DirectoryInfo di = new DirectoryInfo(sourceDir);
foreach (FileInfo fi in di.GetFiles())
{
if (fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf")
{
if (fi.Name.Contains(userName))
{
if (fi.Name.Contains("X"))
{
if(fi.Name.First().ToString().Equals(userNameFirstLetter))
{
if (fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName))
{
fileInfoList.Add(fi);
}
}
}
}
}
}
// Recurse into subdirectories of this directory.
string[] subdirEntries = Directory.GetDirectories(sourceDir);
foreach (string subdir in subdirEntries)
{
// Do not iterate through reparse points
if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
ProcessDir(subdir, userName);
}
}
}
catch (DirectoryNotFoundException exp)
{
throw new DirectoryNotFoundException("Directory not found " + exp.Message);
}
catch (IOException exp)
{
throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message);
}
}
public List<FileInfo> GetFileInfoList()
{
return fileInfoList;
}
}
您不需要递归。
string[] filePaths = Directory.GetFiles(@"c:'SomeDir'", "*.ext", SearchOption.AllDirectories);
您可以这样做:
DirectoryInfo dir = new DirectoryInfo(@"C:'PathName");
IEnumerable<FileInfo> files = dir.GetFiles("*.*");
如果您使用的是C#3.5或更高版本,那么您可以使用LINQ
来过滤它。类似于:
// Only use files with userName in the filename
files = files.Where(f => f.Name.Contains(userName));
或者组合2:
DirectoryInfo dir = new DirectoryInfo(@"C:'PathName");
IEnumerable<FileInfo> files = dir.GetFiles("*.*").Where(f => f.Name.Contains(userName));
如果这是关于获取文件列表,请查看Paul Alan Taylor的答案。
如果您想学习(一点(递归:直接从ProcessDir方法返回文件列表。
使用您提供的代码,至少需要调用,并且容易出错。特别是如果类被重用。
我更改了您代码中的一些内容:
- fileInfoList在ProcessDir内部声明
-
递归调用将结果添加到"当前"结果中。
公共类FileUtility{
public List<FileInfo> ProcessDir(string sourceDir, String userName) { List<FileInfo> fileInfoList = new List<FileInfo>(); try { string userNameFirstLetter = userName.First().ToString(); DirectoryInfo di = new DirectoryInfo(sourceDir); foreach (FileInfo fi in di.GetFiles()) { if (fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf") { if (fi.Name.Contains(userName)) { if (fi.Name.Contains("X")) { if(fi.Name.First().ToString().Equals(userNameFirstLetter)) { if (fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName)) { fileInfoList.Add(fi); } } } } } } // Recurse into subdirectories of this directory. string[] subdirEntries = Directory.GetDirectories(sourceDir); foreach (string subdir in subdirEntries) { // Do not iterate through reparse points if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) { fileInfoList.AddRange(ProcessDir(subdir, userName)); } } } catch (DirectoryNotFoundException exp) { throw new DirectoryNotFoundException("Directory not found " + exp.Message); } catch (IOException exp) { throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message); } return fileInfoList; }
}
注意:您的代码可以得到改进,例如,通过使用"logical and"&&
组合if
语句。
有一种更有效的方法。
string[] filePaths = Directory.GetFiles(rootDirectory,searchPattern,SearchOption.AllDirectories);
您将需要修改searchPattern以覆盖您选择文件的标准。
AFAIK searchPattern的操作类似于正则表达式。
或者,您可以获取与某些文件扩展名匹配的所有文件,然后循环使用它们,根据您的标准
您可能不需要该类的实例。考虑将其设置为静态,如以下所示:
public static class FileUtility
{
private static void ProcessDir(string sourceDir, String userName, List<FileInfo> fileInfoList)
{
try
{
string userNameFirstLetter = userName.First().ToString();
DirectoryInfo di = new DirectoryInfo(sourceDir);
foreach (FileInfo fi in di.GetFiles())
{
if ((fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf")
&& fi.Name.Contains(userName) && fi.Name.Contains("X")
&& fi.Name.First().ToString().Equals(userNameFirstLetter)
&& fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName))
{
fileInfoList.Add(fi);
}
}
// Recurse into subdirectories of this directory.
string[] subdirEntries = Directory.GetDirectories(sourceDir);
foreach (string subdir in subdirEntries)
{
// Do not iterate through reparse points
if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
ProcessDir(subdir, userName, fileInfoList);
}
}
}
catch (DirectoryNotFoundException exp)
{
throw new DirectoryNotFoundException("Directory not found " + exp.Message);
}
catch (IOException exp)
{
throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message);
}
}
public static List<FileInfo> GetFileInfoList(string sourceDir, string userName)
{
List<FileInfo> fileInfoList = new List<FileInfo>();
ProcessDir(sourceDir, userName, fileInfoList);
return fileInfoList;
}
}
此外,您还可以通过&&
将标准进行AND运算,使其更加简洁。