Метод readFromFileAndDecrypt расшифровывает сообщение из файла с
помощью заданного пароля. В строках 291-314 создается экземпляр класса Cipher и инициализируется объект Cipher для расшифрования данных (строки 313-314). В строках 350-352 создается поток ввода FileInputStream для расшифрования файла. В строках 354-355 создается поток ввода CipherInputStream для расшифрования данных из потока FileInputStream. В строках 358-364 осуществляется чтение содержимого файла
из CipherInputStream. В строках 375-383 создается массив байтов, который
содержит расшифрованный текст, который отображается в панели JEditorPane.
На рис. 7.7 отображено содержимое, которое
приложение EncipherDecipher будет зашифровывать и записывать в файл TestFile.txt с использованием пароля «I am a BIG secret!». Справа на рисунке отображено содержимое
файла после нажатия кнопки шифрования Encrypt and Write to File.
Для
получения более подробной информации о JCE посетите Web-сайт JCE по адресу java.sun.com/jce. Обратитесь к документации, содержащей
инструкции по копированию и установке.

name=bookmark202>7.8.2. Паттерн проектирования Decorator
В
рассмотренной программе использовался важный паттерн проектирования Decorator. Метод encryptAndWriteToFile записывает зашифрованные данные в файл.
Однако ни объект CipherOutputStream, ни объект FileOutputStream сами по себе не могут зашифровывать
данные и записать их в файл. Путем «сцепления» этих двух объектов вместе — т.е. передачи объекту FileOutpulStream ссылки на конструктор CipherOutputStream — метод может зашифровать данные и
записать их в файл. Такое «сцепление» является примером паттерна проектирования
Decorator, который позволяет объекту динамически
приобретать новые функциональные возможности. В данном примере объект CipherOutputStream декорирует объект FileOutputStream — CipherOutputStream предоставляет FileOutputStre- ат возможность шифрования данных перед
их записью в файл. Одно из преиму- ществ такого паттерна состоит в том, что
разработчикам не нужно создавать дополнительные классы (например, с
использованием наследования) для расширения функциональных возможностей определенного класса.
Поскольку объект FileOut- putStream может динамически принять поведение
объекта CipherOntputStream, нам не нужно создавать отдельный класс с
именем CipherOutputStream, который будет реализовывать поведения
обоих классов. В строках 227-228 достигается тот же самый результат путем
сцепления этих потоков вместе.