我的程序进入一个目录并搜索pdf文件来解析它们。这个程序一直在运行,所以我需要确保不再重新解析同一个文件。
我使用列表存储文件名,然后检查它们是否在那里。
我的代码在这方面不起作用,如果有人可以看看并看到错误的话会非常感激。
FileInfo[] filePaths = di.GetFiles("*.pdf");
for (int i = 0; i < filePaths.Length; i++)
{
foreach (string fileName in usedFileNames)
{
if (fileName.Equals(filePaths[i].Name))
{
isInList = true;
}
else
{
isInList = false;
}
}
if (isInList == false)
{
PDFReaderChooser chooser = new PDFReaderChooser(filePaths[i].Name);
usedFileNames.Add(filePaths[i].Name);
}
}
答案 0 :(得分:4)
更简洁:
var fileNames = di.GetFiles("*.pdf")
.Select(f => f.Name)
.Where(n => !usedFileNames.Contains(n));
usedFileNames.AddRange(fileNames);
foreach (var fileName in fileNames)
{
var chooser = new PDFReaderChooser(fileName);
}
这很好地抽象出逻辑,从处理它们的逻辑(循环内部)中找出你需要处理的文件名(在循环之外)。
答案 1 :(得分:3)
虽然其他答案是问题的更好解决方案,但它们并不能解释为什么原始代码不起作用。问题是该算法会覆盖isInList变量的值,因此只对列表中的最后一个文件成为true。这可以解决这个问题:
FileInfo[] filePaths = di.GetFiles("*.pdf");
for (int i = 0; i < filePaths.Length; i++)
{
isInList = false
foreach (string fileName in usedFileNames)
{
if (fileName.Equals(filePaths[i].Name))
{
isInList = true;
break;
}
}
if (isInList == false)
{
PDFReaderChooser chooser = new PDFReaderChooser(filePaths[i].Name);
usedFileNames.Add(filePaths[i].Name);
}
}
我想补充说,最好为usedFileNames集合使用HashSet而不是List。哈希集旨在有效地确定它是否包含给定项。如果我没记错的话,该列表会进行线性搜索,这对于大量项目来说效率很低。
答案 2 :(得分:0)
试试这个:
FileInfo[] filePaths = di.GetFiles("*.pdf");
foreach(FileInfo fInfo in filePaths)
{
if (!usedFileNames.Contains(fInfo.Name))
{
PDFReaderChooser chooser = new PDFReaderChooser(fInfo.Name);
usedFileNames.Add(fInfo.Name);
}
}
当我评论你的问题时,你发布的代码不起作用,因为你必须插入一个break语句,如下所示:
for (int i = 0; i < filePaths.Length; i++)
{
bool isInList = false;
foreach (string fileName in usedFileNames)
{
if (fileName.Equals(filePaths[i].Name))
isInList = true;
}
if (isInList == false)
{
Console.WriteLine("Not in list! #{0}", x);
usedFileNames.Add(filePaths[i].Name);
}
}
无论如何,我建议您使用此问题回复中显示的技巧之一。
答案 3 :(得分:0)
LINQ Contains操作会使这更加简洁(假设usedFileNames是List<string>
):
FileInfo[] filePaths = di.GetFiles("*.pdf");
foreach(FileInfo myInfo in filePaths)
{
if (!usedFileNames.Contains(myInfo.Name))
{
PDFReaderChooser chooser = new PDFReaderChooser(myInfo.Name);
usedFileNames.Add(myInfo.Name);
}
}