GetDirectories не может перечислить подпапки папки с именем # 255

Мое приложение С# 3.5 работает на Windows 7 Ultimate, 64 бит. Он выполняет все папки вложенных папок для выполнения своей работы. Однако он терпит неудачу (попадает в бесконечный цикл до исключения StackOverflow.com), если выполняется против папки, имя которой является только одним символом, который равен # 255.

Чтобы воспроизвести, вы можете сделать следующее:

  • запустите Windows Explorer, создав папку C:\Temp в этой папке
  • создайте новую папку и переименуйте ее с помощью Alt-255 (используя цифровую клавиатуру)
  • создать подпапки "first" и "second" there
  • создать подпапки "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:\Temp\1
C:\Temp\2
C:\Temp\
C:\Temp\1
C:\Temp\2
C:\Temp\
C:\Temp\1
C:\Temp\2
C:\Temp\

Итак, как правильно перечислить такие папки вложенных папок?

Ответ 1

Следующая программа работает отлично и не приводит к ошибке.

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([email protected]"\");

Добавление разделителя конечных путей останавливает обрезку, которая появляется в вызове в DirectoryInfo. В приведенном выше примере это означает, что @"C:\Temp\ \" передается в DirectoryInfo, что дает ожидаемые результаты.

Я предполагаю, что вы, вероятно, должны использовать процедуру, которая добавляет только разделитель пути назад, если он еще не присутствует. И вы можете захотеть избежать hardcoding @ "\" в качестве разделителя путей, но для вас теперь нужно понять, что вы знаете, какова основная причина вашей проблемы.

Ответ 2

Символ ASCII 255 полностью не поддерживается Windows. Для визуальных целей он переводит этот символ в символ "_".

Причина? Символ ASCII 255 отображается как невидимый символ, но занимает одно пространство символов, поэтому путаница между этим символом и символом ASCII 32 SPACE. Этот символ работает только в Windows 98 и более низких версиях, включая все версии DOS (если я не ошибаюсь).

РЕДАКТИРОВАТЬ: Windows 7 теперь имеет некоторое исправление с некоторыми расширенными символами. Код должен обрабатываться отлично, если он работает на этой ОС.

Решение? Не используйте этот символ как имя файла и папки, потому что ваша программа.

или

  • Позволяет программе проверять расширенные символы и пропускать их, если они существуют до того, как они будут выполняться бесконечно.

  • Разрешить программе папки с расширенными символами, но если в случае непрерывности цикла, поместите код, который пропустит эту папку и переместится к следующему элементу папки.

  • Ваш код должен работать с Vista и Windows 7, сделать это требование вашей программы.

Ответ 3

Почему у вас есть папка с именем "_"? Это не описательно вообще. Идея папки состоит в том, что вы можете содержать все связанные файлы в этой папке и, возможно, использовать подпапки, чтобы группировать их еще больше; имена папок обычно должны быть описательными - например, у многих сайтов есть папка с именем "css" или "stylesheets". Сомневаюсь, что мне нужно объяснить, для чего они предназначены, поскольку они довольно понятны. Я лично не могу подумайте об одной ситуации, когда я буду использовать 1 символ для имени папки. Лучше всего, на мой взгляд, придерживаться буквенно-цифровых символов и редко использовать символы (это безопаснее, поскольку вы никогда не сталкивались с этими ситуациями в любой операционной системе).