410013796724260
• Webmoney
R335386147728
Z369087728698
Архивирование директорий, zipJava для работы с файлами кроме общего функционала (чтение, запись и т.д.) предоставляет возможность использования zip-архивов. Для этого в пакете java.util.zip определены два класса - ZipInputStream и ZipOutputStream. При работе с архивами еще в 1999 г. был зарегистрирован баг №4244499, связанный с наименованием файлов, использующие не латинские символы. То есть, наименования файлов с кирилицей искажались. И только в версии JDK 7 этот баг был исправлен - в ZIP API добавили новый конструктор, в котором можно явно указывать кодировку: ZipOutputStream (OutputStream out, Charset charset) К тому же, по-умолчанию используется стандартная UTF-8 кодировка. Таким образом, дополнительных библиотек использовать не нужно, можно сразу делать zip-архив. К сожалению, мне не удалось создать нормальный архив с русскоязычными символами в наименованиях файлов и директорий. Поэтому в примерах я использовал библиотеку apache-ant-zip.jar, которая успешно решает вопросы архивации файлов, в названии которых используется кириллица. В качестве примера будем использовать трехуровневую директорию следующей структуры : Архивирование директорииДля правильной кодировки наименований русскоязычных файлов в примере используется метод setEncoding класса ZipOutputStream. private void Zip(String source_dir, String zip_file) throws Exception { // Cоздание объекта ZipOutputStream из FileOutputStream FileOutputStream fout = new FileOutputStream(zip_file); ZipOutputStream zout = new ZipOutputStream(fout); // Определение кодировки zout.setEncoding("CP866"); // Создание объекта File object архивируемой директории File fileSource = new File(source_dir); addDirectory(zout, fileSource); // Закрываем ZipOutputStream zout.close(); System.out.println("Zip файл создан!"); } private void addDirectory(ZipOutputStream zout, File fileSource) throws Exception { File[] files = fileSource.listFiles(); System.out.println("Добавление директории <" + fileSource.getName() + ">"); for(int i = 0; i < files.length; i++) { // Если file является директорией, то рекурсивно вызываем // метод addDirectory if(files[i].isDirectory()) { addDirectory(zout, files[i]); continue; } System.out.println("Добавление файла <" + files[i].getName() + ">"); FileInputStream fis = new FileInputStream(files[i]); zout.putNextEntry(new ZipEntry(files[i].getPath())); byte[] buffer = new byte[4048]; int length; while((length = fis.read(buffer)) > 0) zout.write(buffer, 0, length); // Закрываем ZipOutputStream и InputStream zout.closeEntry(); fis.close(); } } В примере используется рекурсивный метод addDirectory. В этом мтоде после добавления объекта ZipEntry в поток ZipOutputStream записывается содержимое файла. Для этого используется метод write, записывающий в поток массив байтов zout.write(buffer). В завершении ZipEntry закрывается с помощью метода closeEntry(). Результат работы программы можно увидеть в консоли : Добавление директории <Тестовая папка> Добавление файла <Документ Word 1.docx> Добавление файла <Лист Excel 1.xlsx> Добавление файла <Текстовый документ 1.txt> Добавление директории <Уровень 2> Добавление файла <Документ Word 2.docx> Добавление файла <Лист Excel 2.xlsx> Добавление файла <Текстовый документ 2.txt> Добавление директории <Уровень 3.1> Добавление файла <Документ Word 3.1.docx> Добавление файла <Лист Excel 3.1.xlsx> Добавление файла <Текстовый документ 3.1.txt> Добавление директории <Уровень 3.2> Добавление файла <Документ Word 3.2.docx> Добавление файла <Лист Excel 3.2.xlsx> Добавление файла <Текстовый документ 3.2.txt> Zip файл создан! Разархивирование директорииВ примере разархивирования используется файл, созданный в предыдущем примере архивирования директории. Метод Unzip в качестве входного параметра принимает архивный файл. ZipFile позволяет получить все "вхождения" директорий и файлов в архив. После этого в цикле извлекается содержимое архива. private final static String zipDir = "Тестовая папка"; private final static String zipFile = "Тестовая папка.zip"; private final String SLASH_BACK = "/"; private final String CHARSET_CP866 = "CP866"; private void createDir(final String dir) { File file = new File(dir); if (!file.exists()) file.mkdirs(); } private void createFolder(final String dirName) { if (dirName.endsWith(SLASH_BACK)) createDir(dirName.substring(0, dirName.length() - 1)); } private void checkFolder(final String file_path) { if (!file_path.endsWith(SLASH_BACK) && file_path.contains(SLASH_BACK)) { String dir = file_path.substring(0, file_path.lastIndexOf(SLASH_BACK)); createDir(dir); } } private void Unzip(final String zipDir) throws Exception { ZipFile zipFile = new ZipFile(zipDir, CHARSET_CP866); Enumeration<?> entries = zipFile.getEntries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); String entryName = entry.getName(); if (entryName.endsWith(SLASH_BACK)) { System.out.println("Создание директории <" + entryName + ">"); createFolder (entryName); continue; } else checkFolder(entryName); System.out.println("Чтение файла <" + entryName + ">"); InputStream fis = (InputStream) zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(entryName); byte[] buffer = new byte[fis.available()]; // Считываем буфер fis.read(buffer, 0, buffer.length); // Записываем из буфера в файл fos.write(buffer, 0, buffer.length); fis.close(); fos.close(); } zipFile.close() ; System.out.println("Zip файл разархивирован!"); } Результат работы программы можно увидеть в консоли : Чтение файла <Тестовая папка/Уровень 1/Уровень 2.1/Документ Word 2.1.docx> Создание директории <Тестовая папка/Уровень 1/Уровень 2.1/> Чтение файла <Тестовая папка/Уровень 1/Уровень 2.2/Документ Word 2.2.docx> Чтение файла <Тестовая папка/Лист Excel 1.xlsx> Чтение файла <Тестовая папка/Уровень 1/Уровень 2.1/Лист Excel 2.1.xlsx> Чтение файла <Тестовая папка/Документ Word 1.docx> Чтение файла <Тестовая папка/Уровень 1/Уровень 2.2/Текстовый документ 2.2.txt> Чтение файла <Тестовая папка/Уровень 1/Уровень 2.2/Лист Excel 2.2.xlsx> Чтение файла <Тестовая папка/Уровень 1/Документ Word 2.docx> Создание директории <Тестовая папка/> Создание директории <Тестовая папка/Уровень 1/> Чтение файла <Тестовая папка/Уровень 1/Лист Excel 2.xlsx> Чтение файла <Тестовая папка/Текстовый документ 1.txt> Чтение файла <Тестовая папка/Уровень 1/Текстовый документ 2.txt> Чтение файла <Тестовая папка/Уровень 1/Уровень 2.1/Текстовый документ 2.1.txt> Создание директории <Тестовая папка/Уровень 1/Уровень 2.2/> Zip файл разархивирован! Скачать примерИсходный код рассмотренного примера архивирирования многоуровневой директории и разархивирование файла в виде проекта Eclipse можно скачать здесь (56.6 Мб). Библиотека apache-ant-zip.jar, используемая в примере, включена в проект. |