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, используемая в примере, включена в проект. |
