GetDirectories无法枚举#255名称的文件夹的子文件夹

时间:2011-03-20 11:04:42

标签: .net file-io special-characters

我的应用程序是在Windows 7旗舰版64位上运行的C#3.5。它遍历所有文件夹子文件夹以执行其工作。但是,如果针对名称只有一个符号#255的文件夹运行,它会失败(在StackOverflow.com异常之前进入无限循环)。

要重现,您可以执行以下操作:

  1. 运行Windows资源管理器在此文件夹中创建C:\ Temp文件夹
  2. 创建新文件夹并使用Alt-255(使用数字小键盘)重命名
  3. 创建子文件夹“first”和“second”那里
  4. 在Temp
  5. 下创建子文件夹“1”和“2”

    所以你现在有:

    • C:\ 1
    • C:\ 2
    • C:\ \ first
    • C:\ \ second

    对于这样的C:\ Temp文件夹,其子文件夹名为#255(或更多#255个符号),代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    class Program
    {
      public static string[] GetDirectories(string pathToTraverse)
      {
        List<string> result = new List<string>();
    
        foreach (DirectoryInfo subFolder in new DirectoryInfo(pathToTraverse).GetDirectories())
        {
          result.Add(subFolder.FullName);
        }
        return result.ToArray();
      }
    
      public static void TraverseFolders(string folderToTraverse)
      {
        foreach (string subFolder in GetDirectories(folderToTraverse))
        {
          Console.WriteLine(subFolder);
    
          TraverseFolders(subFolder);
        }
      }
    
      static void Main(string[] args)
      {
        TraverseFolders(@"C:\Temp");
      }
    }
    

    将永远不会结束,并会给你如下结果:

    C:\ TEMP \
    C:\温度\ 1个
    C:\ TEMP \ 2
    C:\ TEMP \
    C:\温度\ 1个
    C:\ TEMP \ 2
    C:\ TEMP \
    C:\温度\ 1个
    C:\ TEMP \ 2
    C:\ TEMP \

    那么如何正确枚举此类文件夹子文件夹?

3 个答案:

答案 0 :(得分:3)

以下程序运行完美,不会导致堆栈溢出错误。

using System;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string pathToTraverse = @"C:\Desktop";
            foreach (DirectoryInfo subFolder in new DirectoryInfo(pathToTraverse).GetDirectories())
            {
                System.Console.WriteLine(subFolder);
            }
        }
    }
}

它产生以下输出:

chaff
Python
__history
 
ÿ

倒数第二个显然空白的行实际上是名为Alt + 255的目录。

因此,我认为您的问题与您所显示的代码无关,实际上在您未提交给我们的某些代码中的其他地方。

我在Windows 7上运行VS 2010 Express,目标是.net 3.5。


现在您的更新显示了所有代码,我可以看到发生了什么。 .net代码可能是修剪目录,因此带有空格的文件夹会丢失。

因此@"C:\Temp\ "被裁减为@"C:\Temp\"

我发现以下微不足道的修改避免了无限循环:

TraverseFolders(subFolder+@"\");

添加尾随路径分隔符会停止在对DirectoryInfo的调用中出现的修剪。在上面的示例中,这意味着将@"C:\Temp\ \"传递给DirectoryInfo,从而产生预期结果。

我猜你应该使用一个只添加一个尾随路径分隔符的例程(如果还没有)。并且您可能希望避免将@“\”硬编码为路径分隔符,但是现在您可以知道问题的根本原因是什么。

答案 1 :(得分:1)

Windows不完全支持ASCII字符255。为了视觉起见,它将此字符转换为“_”字符。

原因? ASCII 255字符显示为不可见字符但占用一个字符空间,因此,此字符与ASCII 32 SPACE字符之间存在混淆。此字符仅适用于Windows 98及更低版本,包括所有DOS版本(如果我没有记错的话)。

编辑: Windows 7现在有一些扩展字符的修复程序。如果在该操作系统上运行,则应该正确处理代码。

解决方案? 不要将此字符用作文件和文件夹名称,因为您的程序。

  1. 让程序检查扩展字符并在它无限循环之前跳过它们。

  2. 允许程序使用扩展字符的文件夹,但如果它连续循环,请放置一个代码,跳过该文件夹并移动到下一个文件夹项。

  3. 您的代码应与Vista和Windows 7一起使用,以满足您的计划要求。

答案 2 :(得分:0)

为什么你到底有一个名为“_”的文件夹?它根本不具有描述性。文件夹的概念是你可以包含该文件夹中的所有相关文件,并可能使用子文件夹对它们进行分组;文件夹名称通常应该是描述性的 - 例如,许多网站都有一个名为“css”或“stylesheets”的文件夹。怀疑我需要解释它们的内容,因为它们非常不言自明。我个人不能想到情况,我将使用1个符号作为文件夹名称。在我看来,最好坚持使用字母数字字符并且很少使用符号(因为你从未在任何操作系统上遇到过这种情况,所以它更安全)。