как можно легко проверить, запрещен ли доступ для файла в.NET?

98
задан John Saunders 18 March 2010 в 12:50
поделиться

4 ответа

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

полномочия Файла (даже существование файла) энергозависимы — они могут измениться в любое время. Благодаря Закону Murphy's это особенно включает краткий период между тем, когда Вы проверяете файл и когда Вы пытаетесь открыть его. Изменение еще более вероятно, если Вы находитесь в области, где Вы знаете, что необходимо проверить сначала. Все же странно достаточно этого никогда не будет происходить в Ваших тестовых средах или средах разработки, которые имеют тенденцию быть довольно статичными. Это делает проблему трудной разыскать позже и облегчает для этого вида ошибки превращать его в производство.

то, Что это означает, - то, что все еще необходимо быть в состоянии обработать исключение, если полномочия файла или существование плохи, несмотря на проверку. Код обработки исключений , потребовал , проверяете ли Вы на полномочия файла заранее. Код обработки исключений обеспечивает весь из функциональности проверок полномочий или существования. Кроме того, в то время как обработчики исключений как это, как известно, являются медленными, важно помнить, что диск i/o еще медленнее... партия медленнее... и вызов.Exists () функция или проверка, что полномочия вызовут дополнительное прохождение файловая система.

, Таким образом, начальная проверка прежде, чем попытаться открыть файл и избыточна и расточительна. Нет никакой дополнительной выгоды по обработке исключений, она на самом деле повредит, не поможет, Ваша производительность, она добавляет стоимость с точки зрения большего количества кода, который должен сохраняться, и она может ввести тонкие ошибки в Ваш код. Нет только никакого позитивного аспекта вообще к выполнению начальной проверки. Вместо этого корректная вещь здесь состоит в том, чтобы просто попытаться открыть файл и приложить Ваши усилия к хорошему обработчику исключений, если это перестало работать. То же верно, даже если Вы просто проверяете, существует ли файл. Это обоснование относится любой энергозависимый ресурс.

152
ответ дан 13 revs, 2 users 96% 24 November 2019 в 05:15
поделиться

Во-первых, что сказал Joel Coehoorn.

Также: необходимо исследовать предположения, что underly требование избегать использования попытки/выгоды, если Вы не имеете к. Типичная причина предотвращения логики, которая зависит от исключений (создающий Exception объекты работает плохо), вероятно, не релевантна для кодирования, это открывает файл.

я предполагаю, что, если Вы пишете метод, который заполняет List<FileStream> путем открытия каждого файла в поддереве каталога и Вы ожидали, что большие количества их будут недоступны, Вы могли бы хотеть проверить полномочия файла прежде, чем попытаться открыть файл так, чтобы Вы не получали слишком много исключений. Но Вы все еще обработали бы исключение. Кроме того, существует, вероятно, что-то ужасно неправильно с дизайном Вашей программы, если Вы пишете метод, который делает это.

3
ответ дан Robert Rossney 24 November 2019 в 05:15
поделиться

Быстрый совет для всех, кто придет сюда с похожей проблемой:

Следите за приложениями веб-синхронизации, такими как DropBox. Я просто потратил 2 часа, думая, что выражение "using" (шаблон Dispose) не работает в .NET.

В конце концов я понял, что Dropbox постоянно читает и пишет файлы в фоновом режиме, чтобы синхронизировать их.

Угадайте, где находится моя папка «Проекты Visual Studio»? Внутри папки «Мой Dropbox», конечно.

Поэтому, когда я запускал приложение в режиме отладки, DropBox постоянно обращался к файлам, которые оно читало и записывало для синхронизации с сервером DropBox. Это вызвало конфликты блокировки / доступа.

Так что, по крайней мере, теперь я знаю, что мне нужна более надежная функция открытия файла (например, TryOpen (), которая будет делать несколько попыток). Я удивлен

[Обновление]

Вот моя вспомогательная функция:

/// <summary>
/// Tries to open a file, with a user defined number of attempt and Sleep delay between attempts.
/// </summary>
/// <param name="filePath">The full file path to be opened</param>
/// <param name="fileMode">Required file mode enum value(see MSDN documentation)</param>
/// <param name="fileAccess">Required file access enum value(see MSDN documentation)</param>
/// <param name="fileShare">Required file share enum value(see MSDN documentation)</param>
/// <param name="maximumAttempts">The total number of attempts to make (multiply by attemptWaitMS for the maximum time the function with Try opening the file)</param>
/// <param name="attemptWaitMS">The delay in Milliseconds between each attempt.</param>
/// <returns>A valid FileStream object for the opened file, or null if the File could not be opened after the required attempts</returns>
public FileStream TryOpen(string filePath, FileMode fileMode, FileAccess fileAccess,FileShare fileShare,int maximumAttempts,int attemptWaitMS)
{
    FileStream fs = null;
    int attempts = 0;

    // Loop allow multiple attempts
    while (true)
    {
        try
        {
            fs = File.Open(filePath, fileMode, fileAccess, fileShare);

            //If we get here, the File.Open succeeded, so break out of the loop and return the FileStream
            break;
        }
        catch (IOException ioEx)
        {
            // IOExcception is thrown if the file is in use by another process.

            // Check the numbere of attempts to ensure no infinite loop
            attempts++;
            if (attempts > maximumAttempts)
            {
                // Too many attempts,cannot Open File, break and return null 
                fs = null;
                break;
            }
            else
            {
                // Sleep before making another attempt
                Thread.Sleep(attemptWaitMS);

            }

        }

    }
    // Reutn the filestream, may be valid or null
    return fs;
}
22
ответ дан 24 November 2019 в 05:15
поделиться
public static FileStream GetFileStream(String filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare, ref int attempts, int attemptWaitInMilliseconds)
{            
    try
    {
         return File.Open(filePath, fileMode, fileAccess, fileShare);
    }
    catch (UnauthorizedAccessException unauthorizedAccessException)
    {
        if (attempts <= 0)
        {
            throw unauthorizedAccessException;
        }
        else
        {
            Thread.Sleep(attemptWaitInMilliseconds);
            attempts--;
            return GetFileStream(filePath, fileMode, fileAccess, fileShare, ref attempts, attemptWaitInMilliseconds);
        }
    }
}
-3
ответ дан 24 November 2019 в 05:15
поделиться
Другие вопросы по тегам:

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