C # переместить файл, как только он станет доступным - PullRequest
2 голосов
/ 27 апреля 2010

Мне нужно выполнить следующую задачу:

Попытка переместить файл. Если файл заблокирован, расписание для перемещения, как только оно станет доступным.

Я использую File.Move, которого достаточно для моей программы. Теперь проблемы таковы:

1) Я не могу найти хороший способ проверить, заблокирован ли файл, который мне нужно переместить. Я ловлю System.IO.IOException, но читая другие посты вокруг, я обнаружил, что одно и то же исключение может быть вызвано и по другим причинам.

2) Определение, когда файл разблокирован. Одним из способов сделать это, вероятно, является использование таймера / потока и проверка запланированных файлов, скажем, каждые 30 секунд и попытка их перемещения. Но я надеюсь, что есть лучший способ использования FileSystemWatcher.

Это. Win 3.5 приложение winforms. Любые комментарии / предложения приветствуются. Спасибо за внимание.

Ответы [ 6 ]

4 голосов
/ 27 апреля 2010

Вы должны просто попытаться поймать IOException. Используйте Marshal.GetHRForException, чтобы проверить причину исключения. Уведомление не будет надежным. Другой процесс может снова заблокировать файл перед выполнением File.Move.

2 голосов
/ 27 апреля 2010

Все просто:

        static void Main(string[] args)
        {
            //* Create Watcher object.
            FileSystemWatcher watcher = new FileSystemWatcher(@"C:\MyFolder\");

            //* Assign event handler. 
            watcher.Created += new FileSystemEventHandler(watcher_Created);

            //* Start watching. 
            watcher.EnableRaisingEvents = true;

            Console.ReadLine();
        }


        static void watcher_Created(object sender, FileSystemEventArgs e)
        {
            try
            {
                File.Move(e.FullPath, @"C:\MyMovedFolder\" + e.Name);
            }
            catch (Exception)
            {
                //* Something went wrong. You can do additional proceesing here, like fire-up new thread for retry move procedure.
            }
        }
1 голос
/ 27 апреля 2010

Запланированная повторная попытка исключения (вероятно, увеличение задержки - до определенного момента), вероятно, является самым простым способом достижения этого (ваш (2)). Чтобы сделать это правильно, вам придется сбросить хуки до системного уровня (с кодом ядра), чтобы перехватить событие закрытия файла, которое имеет свои собственные особенности. Это большая работа - на несколько порядков более сложная, чем запланированная повторная попытка. Вы и ваше дело должны сделать этот звонок, но я не знаю ничего эффективного между ними.

1 голос
/ 27 апреля 2010

Это не относится к вашей проблеме, но, как правило, для такого рода действий вам всегда нужно будет сохранять режим «попробуйте и изящно справиться с ошибкой».

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

1 голос
/ 27 апреля 2010

Одной из возможных альтернатив является использование MoveFileEx с флагом MOVEFILE_DELAY_UNTIL_REBOOT. Если у вас нет доступа для перемещения файла прямо сейчас, вы можете запланировать его перемещение при следующей перезагрузке, когда он гарантированно будет доступен (перемещение происходит очень рано в последовательности загрузки).

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

0 голосов
/ 27 апреля 2010

Посмотрите на FileSystemWatcher.

http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(VS.90).aspx

Прослушивает изменение файловой системы уведомления и вызывает события, когда каталог или файл в каталоге, изменения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...