none
Как удалить файл, содержащий картинку,которая только что просматривалась в pictureBox RRS feed

  • Вопрос

  • Простейшая задача.

    В программе надо просматривать фото в папке и удалять ненужные. Файлы(FileInfo ) помещаются в listBox.

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

     обработка клика на кнопку содержит  примерно такой код:

                FileInfo selFile = (FileInfo)listBoxSouseFolder.SelectedItem;
                if (selFile.Exists)
                {
                     curImageSouse =
                        Image.FromFile( @"C:\ProgramData\VMprog\Photo\Job\0.gif");
                    pictureBoxSouse.Image = curImageSouse;
                    selFile.Delete();
                }

    В момент исключения файла возникает ошибка

    "Процесс не может получить доступ к файлу "....jpg", так как этот файл используется другим процессом."

    В коде видно, что я пытался заменить в  pictureBox исходный image другим.

    curImageSouse пытался делать глобальным и локальным. Результат тот же. На большее не хватило фантазии.

    Подскажите, пожалуйста, что я делаю не так и как надо это делать.

    10 сентября 2013 г. 13:31

Ответы

  • Как данные из allFiles попадают в listBox? Через привязку данных: listBox.DataSource = allFiles, или через listBox.Items.Add?

    Сложно что-то советовать, не видя код.

    Ссылка на файл где-то удерживается - всё дело в этом. Проблема в использовании FileInfo. Можно попробовать заносить в listBox не fileInfo, а fileInfo.Name, то есть string (тогда не будет ссылки на файл).

    • Помечено в качестве ответа Miklv 11 сентября 2013 г. 9:25
    10 сентября 2013 г. 17:32

Все ответы

  • Нужно предварительно удалить ссылку на файл из листбокса. Что-то вроде:

    if (selFile.Exists)
    {
        listBox.Items.Remove(selFile);
        ...

    10 сентября 2013 г. 15:02
  • Большое спасибо. Я как-то не подумал про эту ссылку.

    Попробовал вставить.  Ошибка та же.

    Может быть ключ в том, что " файл используется другим процессом". Что это значит. Я не запускал другие процессы. Вроде я все закрыл. Пробовал исключать разные файлы.

    Если убираю показ картинки при выборе текущего, то все работает - удаляется. Значит файл блокируется все же показом картинки.

    Можно, конечно, для показа делать копию файла и его показывать, но это как очень неизящно. Да и эти файлы тоже надо потом удалять.

    10 сентября 2013 г. 15:54
  • Всё зависит от того, как данные занесены в ListBox. Может, через привязку данных? Тогда ссылку нужно удалить из привязанной коллекции.
    10 сентября 2013 г. 16:25
  • В процедуре заполнения ListBox есть локальный массив

    FileInfo[] allFiles= curDir.GetFiles();

    он не существует после выхода из процедуры.

    Для пробы я его сделал глобальным и перед удалением соответствующий элемент массива сделал равным нулю. Это ничего не изменило.

    Мне кажется мы не там ищем. Если я удаляю показ текущего файла в  pictureBox при выборе текущей строки в ListBox то все удаляется. Никакие другие ссылки этому не мешают. С сейчас файл ведет себя так, как будто я открыл его на запись, а потом попытался удалить и осуществляется это в строчках показа:

    curImageSouse =
                Image.FromFile(selFile.FullName);
                    pictureBoxSouse.Image = curImageSouse;

    Коментирование этих строк делает возможным удаление.

    Подскажите, пожалуйста, как быть. Это маленький кусочек большой программы. (тестирую этот кусок изолированно в отдельном проекте). Из-за него не могу закончить программу.

    10 сентября 2013 г. 17:11
  • Как данные из allFiles попадают в listBox? Через привязку данных: listBox.DataSource = allFiles, или через listBox.Items.Add?

    Сложно что-то советовать, не видя код.

    Ссылка на файл где-то удерживается - всё дело в этом. Проблема в использовании FileInfo. Можно попробовать заносить в listBox не fileInfo, а fileInfo.Name, то есть string (тогда не будет ссылки на файл).

    • Помечено в качестве ответа Miklv 11 сентября 2013 г. 9:25
    10 сентября 2013 г. 17:32
  • Сделал новый тест

    В load

    поместил следующий текст

     curImageSouse =
               Image.FromFile(@"C:\Selected\Волга\Ph2278.jpg");
                pictureBoxSouse.Image = curImageSouse;

    после загрузки вижу картинку.

    в обработку нажатия кнопки поместил след текст

    curImageSouse =
                     Image.FromFile(@"C:\ProgramData\VMprog\Photo\Job\0.gif");
                pictureBoxSouse.Image = curImageSouse;
                File.Delete(@"C:\Selected\Волга\Ph2278.jpg");

    В последней строчке программа встает с той же диагностикой.

    Здесь нет никаких объектов, ссылающихся на файл, кроме curImageSouse и  pictureBoxSouse

    Каким образом освободить файл от захвата. Больше никакого работающего кода нет. Все остальное закоментировано.  Разработка в VS2010.

    Может быть у Вас этот код(с заменой ссылки на фото) ведет по другому?

    curImageSouse объявлен глобально как Image

    10 сентября 2013 г. 19:21
  • Проблема решена. Оказывается все очень просто!

    Из пары подозреваемых операторов (см прошлый пример) оставил только один

    curImageSouse =
               Image.FromFile(@"C:\Selected\Волга\Ph2278.jpg");

    т.е картинка считывается, но не показывается. Запускаю - ошибка осталась.

    Стал внимательнее читать про Image

    Есть метод

    Dispose - освобождение ресурсов. попробовал- все работает

    Поскольку захватываем файл в одном методе, а освобождаем в другом, по переменная

    Image curImageSouse

    должена быть глобальной по отношению к обоим методам.

    Большое спасибо Retalvik-у. Его  фраза надо искать что захватывает мне очень помогла.

    11 сентября 2013 г. 9:24