Ian A Davidson
Способ получения информации о файлах с слишком длинным именем-это P/Invoke to the Windows API. Я считаю, что это то, что библиотеки, которые Золтан has linked to will be doing under the hood (на самом деле первый даже ссылается на некоторые страницы об этом), поэтому я не буду добавлять к этой информации здесь.
Я предполагаю, что исключение происходит, когда вы пытаетесь создать FileInfo, а не при получении списка файлов. В этом случае у вас уже есть пути, так что вы можете либо перехватить исключение, либо проверить длину пути, прежде чем пытаться построить FileInfo, и сделать что - то еще в этом случае-например, исключить путь из вашего списка, или сообщить, что путь слишком длинный, или попытаться получить необходимую информацию через P/Invoke (или с помощью библиотеки, упомянутой выше). Золтан).
Учитывая, что вы пытаетесь получить всю информацию о файлах в подкаталоге, вам, вероятно, также следует что-то сделать, если вам отказано в разрешениях и т. д., Поэтому я бы пошел с захватом исключения. (Кроме того, проверка того, превышает ли путь к файлу ограничения по длине, является более сложной задачей, чем просто проверка его длины, поскольку имеет значение как путь, так и длина имени файла. Такие проверки просто замедлят цикл).
Кроме того, вы создаете FileInfo для каждого файла четыре раза. Я считаю, что каждый экземпляр будет кэшировать многие свойства файла при построении, так что это будет неоправданно медленно. (См. примечание в примерах FileInfo[^])
Имея все это в виду, независимо от проблемы слишком длинного пути, я бы серьезно рассмотрел возможность изменения этого кода.
Боюсь, что я ничего не знаю о синтаксисе "select", который вы использовали, поэтому, если бы я переделал это, я бы, вероятно, сделал что-то вроде этого:
string path = @"D:\Directory";
string[] filePaths = Directory.GetFiles(path, ".", SearchOption.AllDirectories);
foreach (string f in filePaths)
{
try
{
FileInfo info = new FileInfo(f);
ListViewItem item = new ListViewItem(new string[] {
info.DirectoryName, // Note use of this instead of Directory.ToString() !!
info.Name.ToString(),
info.CreationTime.ToString(),
info.Length.ToString()});
// Do what you need to do with "item"
}
catch(PathTooLongException)
{
// Ignore, or add listview item to report error, or
// do something to try to get the information
// (e.g. P/Invoke to the Windows API).
// Note since you already have the full path name, you could use
// System.IO.Path to get the directory and file name.
// E.g.
ListViewItem item = new ListViewItem(new string[] {
Path.GetDirectoryName(f),
Path.GetFileName(f),
"Path too long", /* Error message in "Created Time" field. This is only an example, you probably don't want to do this in real application! Maybe have an additional "error" field? */
""});
// Do what you need to do with "item"
}
catch(SecurityException)
{
// Ignore, or add listview item reporting permission denied, as above.
}
catch(UnauthorizedAccessException)
{
// Ignore, or add listview item reporting permission denied, as above.
}
}
С уважением,
Иан.