1

今天在做一个项目时,我在 .NET 中遇到了这种奇怪的行为。

我正在获取文件名列表并将它们添加到对象中。但是,我需要根据已知的“坏”名称列表过滤传入的名称,这导致我这样做。(我绝不是高级 C# 编码器,仍然只是学习它。)但是,因为它导致aspnet_wp.exe进程无限期地以 100% 运行,所以我认为我在语言上做错了。

这是我的代码供参考:

List<string> localFiles = new List<string>(); 
// I was worried the object was causing the issue so dumbed it down to this with no changed.

string path = "//<file share>/<dir>/"; 
// As I commented below yes, it's slow when it works but it's clearly not working when using the if();

List<string> omitNames = new List<string>();
omitNames.Add("Thumbs.db"); 
// This is the only item in the list when it breaks also.

FileInfo[] localFileList = new DirectoryInfo(path).GetFiles();
foreach ( FileInfo item in localFileList )
{
    if(!omitNames.Contains(item.Name))
    {
        localFiles.Add(path + itemName);
    }
}

谁能解释为什么这段代码作为无限循环运行?看来真的不应该。另外,我意识到使用 aList可能不是最好的方法。有没有另一种方法可以干净地实现这一点?

注释掉if(!){}foromitNames可以让代码正常运行。(虽然显然结果没有被过滤。)

更新:要求将其放入控制台应用程序中,您将在下面找到该应用程序。然而它完美地工作。另一件事是有人建议我尝试简单地将其与字符串进行比较。但是如果改为这样,就会发生完全相同的事情:

if(item.Name != "Thumbs.db")
{
    localFiles.Add(path + itemName);
}

控制台应用程序(有效):

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LoopKiller
{
class Program
{

    static void Main(string[] args)
    {

        List<string> omitNames = new List<string>();
        List<string> localFiles = new List<string>();

        omitNames.Add("Thumbs.db");

        FileInfo[] localFileList = new DirectoryInfo("c:/test/").GetFiles();

        foreach (FileInfo item in localFileList)
        {
            if (!omitNames.Contains(item.Name))
            {
                Console.WriteLine("Adding " + item.Name + " to localFiles.");
                localFiles.Add(item.Name);
                Console.WriteLine("Item added to localFiles.");
            }
        }

        foreach (string item in localFiles)
        {
            Console.WriteLine(item);
        }

        Console.ReadLine();

    }
}
}
4

3 回答 3

2

这是不是更快?

foreach (string item in Directory.GetFiles("c:/test/", "*.*").Select(Path.GetFileName())
    {
        if (!omitNames.Contains(item))
        {
            Console.WriteLine("Adding " + item.Name + " to localFiles.");
            localFiles.Add(item.Name);
            Console.WriteLine("Item added to localFiles.");
        }
    }
于 2012-08-09T21:28:03.040 回答
1

试试 Directory.EnumerateFiles。如果您只需要文件名作为字符串,那么为什么要获取整个 FileInfo?我同意把它放在一个哈希集中。

Directory.EnumerateFiles

如果问题出在 !omitNames.Contains(item.Name) 上,仍然无济于事。那里发生了一些奇怪的事情,因为这应该是一个非常非常快的电话。

这会在 2 毫秒内针对 161 个文件的目录运行,并正确跳过这两个文件。

public void testFileFilter()
    {
        string path = @"c:\temp\";
        int pathLen = path.Length;
        string[] badNames = { "1692.pdf", "readme.htm" };
        List<string> goodNames = new List<string>();
        string fn;
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        foreach(String fp in System.IO.Directory.EnumerateFiles(path))
        {
            //System.Diagnostics.Debug.WriteLine(fp);
            fn = fp.Substring(pathLen);
            //System.Diagnostics.Debug.WriteLine(fn);
            if(badNames.Contains(fn))
            {
                //fn = fp.Substring(pathLen);
            }
            else
            {
                goodNames.Add(fn);
            }
        }
        sw.Stop();
        System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds.ToString());
        System.Diagnostics.Debug.WriteLine(goodNames.Count());
    }    
于 2012-08-09T21:23:06.517 回答
0

尝试以下操作:

List<string> localFiles = new List<string>();
// I was worried the object was causing the issue so dumbed it down to this with no changed.

string path = "//<file share>/<dir>/";
// As I commented below yes, it's slow when it works but it's clearly not working when using the if();

List<string> omitNames = new List<string>();
omitNames.Add("Thumbs.db");
// This is the only item in the list when it breaks also.

localFiles = (from files in new DirectoryInfo(path).GetFiles() where !omitNames.Contains(files.Name) select path + files.Name).ToList<string>();

至于你为什么有这个问题,我不知道。您可以尝试在循环中放置一个断点并进行调试。我发现调试可以使大多数问题变得清晰。例如,锁定文件信息的获取。

于 2012-08-09T21:41:11.043 回答