Невозможно переместить файл, поскольку он используется другим процессом - моей программой? - PullRequest
1 голос
/ 17 апреля 2010

Моя программа не может File.Move или File.Delete файл, потому что он используется "другим процессом", но на самом деле его использует моя собственная программа.

Я использую Directory.GetFiles для первоначального получения путей к файлам, и оттуда я обрабатываю файлы, просто просматривая их имена и обрабатывая информацию таким образом. Следовательно, все, что я делаю, это работаю с самими строками, верно? После этого я пытаюсь переместить файлы в каталог «Обработано». Почти все они обычно перемещаются, но время от времени они просто не двигаются, потому что они используются моей программой.

Почему большинство из них движутся, но один или два остаются здесь? Могу ли я что-нибудь сделать, чтобы освободить файл? Там нет потоков, чтобы закрыть.

Редактировать Вот код:

public object[] UnzipFiles(string[] zipFiles)
    {
        ArrayList al = new ArrayList(); //not sure of proper array size, so using arraylist
        string[] files = null;

        for (int a = 0; a < zipFiles.Length; a++)
        {
            string destination = settings.GetTorrentSaveFolder() + @"\[CSL]--Temp\" + Path.GetFileNameWithoutExtension(zipFiles[a]) + @"\";
            try
            {
                fz.ExtractZip(zipFiles[a], destination, ".torrent");

                files = Directory.GetFiles(destination, 
                    "*.torrent", SearchOption.AllDirectories);

                for (int b = 0; b < files.Length; b++)
                    al.Add(files[b]);
            }

            catch(Exception e)
            {}
        }

        try
        {
            return al.ToArray(); //return all files of all zips
        }
        catch (Exception e)
        {
            return null;
        }
    }

Это называется из:

try
                {
                    object[] rawFiles = directory.UnzipFiles(zipFiles);
                    string[] files = Array.ConvertAll<object, string>(rawFiles, Convert.ToString);
                    if (files != null)
                    {
                        torrents = builder.Build(files);
                        xml.AddTorrents(torrents);
                        directory.MoveProcessedFiles(xml);
                        directory.MoveProcessedZipFiles();
                    }
                }
                catch (Exception e)
                { }

Поэтому строитель строит объекты класса Torrent. Затем я добавляю объекты класса Torrent в xml-файл, в котором хранится информация о нем, и затем пытаюсь переместить обработанные файлы, использующие xml-файл, в качестве справки о том, где находится каждый файл.

Несмотря на то, что для большинства файлов все работает нормально, я получу IOException о том, что он в конечном итоге используется другим процессом:

public void MoveProcessedZipFiles()
    {
        string[] zipFiles = Directory.GetFiles(settings.GetTorrentSaveFolder(), "*.zip", SearchOption.TopDirectoryOnly);

        if (!Directory.Exists(settings.GetTorrentSaveFolder() + @"\[CSL] -- Processed Zips"))
            Directory.CreateDirectory(settings.GetTorrentSaveFolder() + @"\[CSL] -- Processed Zips");

        for (int a = 0; a < zipFiles.Length; a++)
        {
            try
            {
                File.Move(zipFiles[a], settings.GetTorrentSaveFolder() + @"\[CSL] -- Processed Zips\" + zipFiles[a].Substring(zipFiles[a].LastIndexOf('\\') + 1));
            }
            catch (Exception e)
            {
            }
        }
    }

Ответы [ 3 ]

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

Судя по вашим комментариям, это действительно пахнет как утечка ручки. Затем, глядя на ваш код, fz.ExtractZip(...) выглядит как лучший кандидат для использования файловых дескрипторов, и, следовательно, утечка их.

Является ли тип fz частью вашего кода или сторонней библиотеки? Если он находится внутри вашего кода, убедитесь, что он закрывает все свои дескрипторы (самый безопасный способ - через блоки using или try - finally). Если это часть сторонней библиотеки, проверьте документацию и посмотрите, требует ли она какой-либо очистки. Вполне возможно, что он реализует IDisposable; в таком случае поместите его в блок using или убедитесь, что он правильно расположен.

Линия catch(Exception e) {} ужасно плохая практика. Таким способом вы должны избавляться от исключений только тогда, когда точно знаете, какое исключение может быть выдано и почему вы хотите его игнорировать. Если исключение, которое ваша программа не может обработать, происходит, лучше для нее завершиться с описательным сообщением об ошибке и ценной отладочной информацией (например: тип исключения, трассировка стека и т. Д.), Чем игнорировать проблему и продолжить, как будто ничего не произошло неправильно, потому что исключение означает, что что-то определенно пошло не так .

Короче говоря, самый быстрый подход к отладке вашей программы:

  1. замените ваши общие catch ers finally блоков
  2. добавить / переместить любой соответствующий код очистки в finally блоки
  3. обратите внимание на любое исключение, которое вы получите: куда была брошена форма? что это за исключение? что в документации или комментариях к коду говорится о методе, который его вызывает? и так далее.
  4. Или
    4.1. Если тип fz является частью вашего кода, поищите утечки там.
    4.2. Если это часть сторонней библиотеки, просмотрите документацию (и подумайте о том, чтобы получить поддержку от автора).

Надеюсь, это поможет

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

Класс Path обрабатывал несколько файлов, чтобы получить их имена. Несмотря на то, что мне не удалось воспроизвести ту же проблему, форсирование сборки мусора с использованием GC.Collect в конце фазы «обработки» моей программы успешно решило проблему.

Еще раз спасибо всем, кто помог. Я многому научился.

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

Что это значит: "нет потоков, которые нужно закрыть"? Вы имеете в виду, что вы не используете потоки или что вы их закрываете?
Я считаю, что у вас, тем не менее, есть какой-то открытый поток.
У вас есть статические классы, которые используют эти файлы?
1. Попробуйте написать простое приложение, которое будет анализировать только перемещение и удаление файлов, посмотрите, будет ли это работать.
2. Напишите здесь несколько фрагментов кода, которые работают с вашими файлами.
3. Попробуйте использовать unlocker, чтобы дважды убедиться, что у вас нет других файлов, использующих эти файлы: http://www.emptyloop.com/unlocker/ (не забудьте проверить файлы на вирусы:))

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