Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > ImageIcon и нежелательная буферизация


Автор: feanor59 26.10.2009, 17:00
Суть в следующем.
Имеется метод работы с изображением, изменяющий его размеры.
Там есть строчки:
Код

ImageIcon imageIcon = new ImageIcon(imageFile.getPath());
int width = imageIcon.getIconWidth();
int height = imageIcon.getIconHeight();
...

Так вот. 
Сначала имеем некоторый файл, открытый как
Код

File uploadedFile = new File("file.jpg");

При первом использовании метода, всё работает отлично, но если в дальнейшем изменить содержание файла file.jpg, то при
его открытии 
Код

ImageIcon imageIcon = new ImageIcon(imageFile.getPath());
 его содержание подменяется содержанием оригинального файла, т. е. того, что был изменён первым.
Как можно сбросить этот буфер?

Автор: magicfly 26.10.2009, 22:04
Вы закрываете файл и поток после работы?

Автор: feanor59 27.10.2009, 10:52
Цитата(magicfly @ 26.10.2009,  22:04)
Вы закрываете файл и поток после работы?

Да, разумеется. Более того, после внесения изменений в графический файл, они отображаются в просмотрщиках изображений, т. е.  запись действительно происходит, а не остаётся в кеше. Но тем не менее, при ImageIcon imageIcon = new ImageIcon(filePath); imageIcon хранит дескриптор старого файла (к примеру разрешение изображения, полученного из imageIcon соответствует разрешению старого файла). И, соответственно, при записи imageIcon в файл, записывается старое изображение.

Автор: mgarin 28.10.2009, 05:17
Натыкался на эти грабли smile
Это буфер непосредственно ImageIcon, точнее даже Image который в нем хранится
При своем создании он подкачивает один раз ресурсы из файла и в дальнейшем,
в течение жизни ява приложения использует уже подкачанный ранее файл при повторном обращении.

Сбросить, если мне не изменяет память, можно вот так:
Код
imageIcon.getImage ().flush ();

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

Еще точно помню всегда свежее изображение подкачивается если его брать вот так:
Код
Toolkit.getDefaultToolkit ().createImage ( imageFile.getPath() );


А вот такой метод опять же заставит вас наткнуться на грабли кэша:
Код
Toolkit.getDefaultToolkit ().getImage ( imageFile.getPath() );


Причем если посмотреть комментарий 2го метода (getImage):
Цитата
/**
     * Returns an image which gets pixel data from the specified file,
     * whose format can be either GIF, JPEG or PNG.
     * The underlying toolkit attempts to resolve multiple requests
     * with the same filename to the same returned Image.
     * <p>
     * Since the mechanism required to facilitate this sharing of
     * <code>Image</code> objects may continue to hold onto images
     * that are no longer in use for an indefinite period of time,
     * developers are encouraged to implement their own caching of
     * images by using the {@link #createImage(java.lang.String) createImage}
     * variant wherever available.
     ...
    */


Т.е. при использовании метода createImage подразумевается что разработчик сам задействует свой некий механизм кэша ;)

Кстати, к вопросу, почему ImageIcon тоже кэширует это дело:
Код
    public ImageIcon(String filename, String description) {
    image = Toolkit.getDefaultToolkit().getImage(filename);
        if (image == null) {
            return;
        }
    this.filename = filename; 
        this.description = description;
    loadImage(image);
    }


Toolkit.getDefaultToolkit().getImage(filename); - ничего не напоминает? ;)

Автор: feanor59 28.10.2009, 21:45
mgarin, огромное спасибо! пофиксил.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)