Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
[Назад]

Библиотека примеров приложений Java

Оглавление
Выбор файлов
Простейший редактор текста
Копирование файлов UNICODE
Сохранение объекта Java в файле
Произвольные классы и файлы
Буферизация потоков
Разбор конфигура-
ционного файла

Работа с консолью
Работа с классом PrintWriter
Разбор строк класса String
Загрузка и просмотр изображений
Потоки в оперативной памяти
Конвейерные потоки
Комбинирование двух потоков
Комбинирование нескольких потоков
Поиск слова в текстовом файле
Произвольный доступ к файлу
Информация о файле
Работа с каталогами
Просмотр содержимого каталога
Просмотр каталога с фильтром
Панель для выбора каталога
Список системных свойств
Сохранение списка системных свойств
Контрольная сумма файла
Копирование, переименование, удаление файлов
Архивы ZIP
Создание архива ZIP
Распаковка архива ZIP
Обход дерева каталогов

Назад Вперед

7.25. Вычисление контрольной суммы файла

В примере демонстрируется использование библиотеки классов java.util.zip для вычиления контрольной суммы файла по методам CRC-32 и Adler-32.

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Немного теории

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

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

В библиотеке классов java.util.zip есть классы и интерфейсы, намного упрощающие данную задачу. Это классы CRC32, Adler32 и интерфейс Checksum.

Интерфейс Checksum

Интерфейс Checksum определяет методы, применяющиеся при подсчете контрольной суммы. Это методы update, getValue и reset.

Метод update существует в виде двух реализаций:

public abstract void update(int b);
public abstract void update(byte b[],
  int off, int len);

Первая из них обновляет контрольную сумму значением одного байта, а вторая - значениями массива байт.

Метод getValue возвращает текущее значение контрольной суммы:

public abstract long getValue();

Метод reset сбрасывает значение контрольной суммы в исходное состояние:

public abstract void reset();

Классы CRC32 и Adler32

Классы CRC32 и Adler32 предоставляют в ваше распоряжение две различные готовые реализации интерфейса Checksum, использующие 32-разрядное суммирование. Первый из них реализует алгоритм CRC-32, а второй - Adler-32 (более быстродействующий).

Для того чтобы организовать в своем приложении вычисление контрольной суммы файла с применением классов CRC32 или Adler32, вам вначале нужно создать объект одного из этих классов, воспользовавшись для этого соответствующим конструктором. Заметим, что конструкторы этих классов не имеют параметров.

Далее вам нужно создать входной поток для исследуемого файла и организовать его чтение блоками в цикле. На каждой итерации цикла вы должны вызывать метод update класса CRC32 или Adler32.

После завершения цикла искомая контрольная сумма может быть получена методом getValue, определенным в этих классах.

Описание примера

Наше приложение позволяет выбирать файлы с помощью стандартной диалоговой панели класса FileDialog, определяя для них контрольные суммы с применением алгоритмов CRC-32 и Adler-32.

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

pic1.gif (5859 bytes)

Рис. 1. Просмотр контрольных сумм файлов

Рассмотрим наиболее важные фрагменты исходного текста приложения.

Когда пользователь выбирает из меню File строку Open, управление передается методу actionPerformed.

Данный метод создает и отображает на экране диалоговую панель выбора входного файла, получает путь к выбранному пользователем файлу, сохраняет его в переменной szPath и показывает в окне приложения:

if(e.getSource().equals(miOpen))
{
  fdlg = new FileDialog(this, "Open file", 
    FileDialog.LOAD);
  fdlg.show();
      
  String szPath = fdlg.getDirectory() +
    fdlg.getFile();
      
  ta.append("Open: " + szPath  + "\n");
  . . .
}

Далее мы два раза вызываем метод calculate, определенный в нашем приложении, который возвращает текстовое представление значения контрольной суммы:

ta.append("CRC-32: " +
  calculate(szPath, new CRC32()) + "\n");
        
ta.append("Adler-32: " +
  calculate(szPath, new Adler32()) + "\n");

Через первый параметр этому методу передается путь к файлу, а через второй - ссылка на класс, определяющий метод вычисления контрольной суммы.

Как устроен метод calculate?

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

String s = "";
byte[] buf = new byte[8000];
int nLength = 0;
    
try 
{
  FileInputStream fis = 
    new FileInputStream(szPath);
  . . .
}

Далее мы организуем чтение из потока в цикле блоками по 8000 байт (значение, выбранное нами произвольно), с периодическим обновлением контрольной суммы методом update:

while(true)
{
  nLength = fis.read(buf);
  if(nLength < 0)
    break;
          
  cs.update(buf, 0, nLength);
}

После достижения конца файла связанный с ним поток закрывается, а значение контрольной суммы извлекается методом getValue:

fis.close();
. . .
s = new Long(cs.getValue()).toString();
return s;

Мы преобразуем его в текстовую строку класса String и возвращаем вызвавшему методу.


Назад Вперед

[Назад]