Directory.EnumerateFiles => UnauthorizedAccessException

Да, иногда. Проблема, которую я вижу, состоит в том, что много людей, хотя они знают их, они не знают, как действительно применить их. Большинство людей возвращается назад к связанным спискам массивов и т.д. Они сделают задание в большинстве случаев как более усовершенствованную структуру данных (иногда, действительно необходимо "ударить его" в место), они просто менее эффективны. Люди склонны делать то, что легче для них, но это - не обязательно лучший способ сделать что-то. Я не могу дать сбой их, я уверен, что делаю это также, но именно поэтому Вы не видите много "усовершенствованных" понятий в программировании.

37
задан tshepang 14 February 2014 в 11:16
поделиться

2 ответа

На основании ответа Струдсо, но в качестве методов расширения для FileInfo и DirectoryInfo.

public static IEnumerable<FileInfo> EnumerateFilesSafe(this DirectoryInfo dir, string filter = "*.*", SearchOption opt = SearchOption.TopDirectoryOnly)
{
    var retval = Enumerable.Empty<FileInfo>();

    try { retval = dir.EnumerateFiles(filter); }
    catch { Debug.WriteLine("{0} Inaccessable.", dir.FullName); }

    if (opt == SearchOption.AllDirectories)
        retval = retval.Concat(dir.EnumerateDirectoriesSafe(opt: opt).SelectMany(x => x.EnumerateFilesSafe(filter, opt)));

    return retval;
}

public static IEnumerable<DirectoryInfo> EnumerateDirectoriesSafe(this DirectoryInfo dir, string filter = "*.*", SearchOption opt = SearchOption.TopDirectoryOnly)
{
    var retval = Enumerable.Empty<DirectoryInfo>();

    try { retval = dir.EnumerateDirectories(filter); }
    catch { Debug.WriteLine("{0} Inaccessable.", dir.FullName); }

    if (opt == SearchOption.AllDirectories)
        retval = retval.Concat(retval.SelectMany(x => x.EnumerateDirectoriesSafe(filter, opt)));

    return retval;
}
0
ответ дан 9 October 2019 в 23:27
поделиться
1113 Я понимаю, что это MoveNext вызывает исключение.

Я пытался написать метод, который обходит последовательность и пытается игнорировать MoveNext исключения. Однако я не уверен, что MoveNext продвигает позицию, когда генерирует исключение, так что это также может быть бесконечный цикл. Это также плохая идея, потому что мы будем полагаться на детали реализации.

Но это просто так весело!

public static IEnumerable<T> SafeWalk<T> (this IEnumerable<T> source)
{
    var enumerator = source.GetEnumerator();
    bool? hasCurrent = null;

    do {
        try {
            hasCurrent = enumerator.MoveNext();
        } catch {
            hasCurrent = null; // we're not sure
        }

        if (hasCurrent ?? false) // if not sure, do not return value
            yield return enumerator.Current;

    } while (hasCurrent ?? true); // if not sure, continue walking
}

foreach (var file in Directory.EnumerateFiles("c:\\", "*", SearchOption.AllDirectories)
                              .SafeWalk())
{
    // ...
}

Это будет работать только в том случае, если следующие условия верны для реализации каркаса этого итератора (см. FileSystemEnumerableIterator<TSource> в Reflector для справки ):

  • MoveNext продвигает свою позицию, когда он терпит неудачу;
  • Когда MoveNext терпит неудачу на последнем элементе, последующие вызовы возвратят false вместо того, чтобы вызвать исключение;
  • Это поведение согласованно для разных версий .NET Framework;
  • Я не допустил логических или синтаксических ошибок.

Даже если это работает, пожалуйста, никогда не используйте его в производстве!
Но мне действительно интересно, если это работает.

3
ответ дан 27 November 2019 в 04:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: