учитывая zip-файл с несколькими вложенными структурами каталогов, как мне распаковать его в ту же древовидную структуру? предоставляет ли ZipFile.entries() перечисление в любом порядке?
разархивируйте zip-файл в той же иерархии, используя java.util.ZipFile
Ответы (4)
Zip не предлагает структуру каталогов как таковую. Древовидная структура построена с полным путем к каждой записи. ZipFile перечисляет записи так же, как они были добавлены в файл.
Примечание: java.util.ZipEntry.isDirectory() просто проверяет, является ли последний символ имени «/», вот как это работает.
Что вам нужно, чтобы извлечь файлы в тот же каталог. Затем разберите имя так:
for(ZipEntry zipEntry : java.util.Collections.list(zipFile.entries())){//lazislav
String name = zipEntry.getName();
int idx = name.lastIndexOf('/');
if (idx>=0) name=name.substring(idx)
if (name.length()==0) continue;
File f = new File(targetDir, name);
}
Это должно сделать это более или менее (вам все еще нужно позаботиться о повторяющихся именах файлов и т. д.)
Это мое.
В файле вы указываете файл, который хотите развернуть в целевом каталоге, вы должны указать целевое местоположение как «новый файл («/tmp/foo/bar»)». Если вы хотите извлечь в текущий каталог, вы можете указать targetDir = новый файл ("".")
public static void unzip(File file, File targetDir) throws ZipException,
IOException {
targetDir.mkdirs();
ZipFile zipFile = new ZipFile(file);
try {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File targetFile = new File(targetDir, entry.getName());
if (entry.isDirectory()) {
targetFile.mkdirs();
} else {
InputStream input = zipFile.getInputStream(entry);
try {
OutputStream output = new FileOutputStream(targetFile);
try {
copy(input, output);
} finally {
output.close();
}
} finally {
input.close();
}
}
}
} finally {
zipFile.close();
}
}
private static void copy(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[4096];
int size;
while ((size = input.read(buffer)) != -1)
output.write(buffer, 0, size);
}
Работал на меня. Удачи.
Вот тот, который я использую все время. Он должен работать сразу после копирования/вставки и при любых обстоятельствах.
public static File unzip(File inFile, File outFolder)
{ final int BUFFER = 2048;
try
{
BufferedOutputStream out = null;
ZipInputStream in = new ZipInputStream(
new BufferedInputStream(
new FileInputStream(inFile)));
ZipEntry entry;
while((entry = in.getNextEntry()) != null)
{
//System.out.println("Extracting: " + entry);
int count;
byte data[] = new byte[BUFFER];
//We will try to reconstruct the entry directories
File entrySupposedPath = new File(outFolder.getAbsolutePath()+File.separator+entry.getName());
//Does the parent folder exist?
if (!entrySupposedPath.getParentFile().exists()){
entrySupposedPath.getParentFile().mkdirs();
}
// write the files to the disk
out = new BufferedOutputStream(
new FileOutputStream(outFolder.getPath() + "/" + entry.getName()),BUFFER);
while ((count = in.read(data,0,BUFFER)) != -1)
{
out.write(data,0,count);
}
out.flush();
out.close();
}
in.close();
return outFolder;
}
catch(Exception e)
{
e.printStackTrace();
return inFile;
}
}
Зачем вам порядок?
Если запись ZipFile имеет имя /a/b/c/file.txt
, вы можете определить имя каталога /a/b/c
, а затем создать в дереве каталог с именем a/b/c
.