Распаковать с томом хранилища:
Осторожно: Таким образом, он создает копии, если вы разархивируете один и тот же файл .zip несколько раз, в то время как мой оригинальный код в первом посте (который вы не можете использовать для SDкарточка) не делает, но вместо этого автоматически перезаписывает!
try {
InputStream is = getContentResolver().openInputStream(myZip.getUri());
BufferedInputStream bis = new BufferedInputStream(is);
ZipInputStream zis = new ZipInputStream(bis);
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
String fileName = null;
try {
fileName = zipEntry.getName();
fileName = fileName.replace("\\",File.separator).replace("/",File.separator);
int p=fileName.lastIndexOf(File.separator);
DocumentFile destFolder = myDestFolder; //DocumentFile of the destination folder
String destName = fileName;
if (p>=0) {
String[] split = fileName.split(File.separator);
//If the .zip file contains multiple folder levels, this is where you
//have to check and then create them, e.g. for 3 levels:
if(split.length==1) {
destFolder = myFolder;
destName = filename;
} else if(split.length==2) {
if(mySubFolder==null) {
mySubFolder = myFolder.createDirectory(split[0]);
}
destFolder = mySubFolder;
destName = split[1];
} else if(split.length==3) {
if(mySubFolder==null) {
mySubFolder = myFolder.createDirectory(split[0]);
}
if(mySubSubFolder==null) {
mySubSubFolder = mySubFolder.createDirectory(split[1]);
}
destFolder = mySubSubFolder;
destName = split[2];
}
}
DocumentFile df = null;
//Now you have to tell it what file extensions ("MIME" type) you want to use, e.g.:
if(destName.endsWith(".txt")) {
df = destFolder.createFile("text/plain",destName.substring(0,destName.length()-4));
} else if(destName.endsWith(".jpg")) {
df = destFolder.createFile("image/jpeg",destName.substring(0,destName.length()-4));
}
OutputStream out = getContentResolver().openOutputStream(df.getUri());
BufferedOutputStream bos = new BufferedOutputStream(out);
long zipfilesize = zipEntry.getSize();
byte[] buffer = new byte[10000];
int len = 0;
int totlen = 0;
while (((len = zis.read(buffer, 0, 10000)) > 0) && (totlen < zipfilesize)) {
bos.write(buffer, 0, len);
totlen += len;
}
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
return;
}
}
is.close();
bis.close();
zis.close();
} catch (IOException e2) {
e2.printStackTrace();
}
Редактировать: Важно : java.util.zip
не устанавливает size
или compressedSize
(вернет "-1"), поэтому этот код будет создавать только файлы размером 0B с zip-файлами, которые были созданы библиотекой - zip-файлы, созданные вручную (например, с помощью WinRar), работают нормально.Чтобы исправить это, замените
while (((len = zis.read(buffer, 0, 10000)) > 0) && (totlen < zipfilesize)) {
на
while (((len = zis.read(buffer, 0, 10000)) > 0)) {
Это можно сделать, потому что:
вызов ZipInputStream.getNextEntry () позиционируетInputStream в начале записи и, следовательно, предоставление ZipInputStream является эквивалентом предоставления InputStream ZipEntry.
Source: https://stackoverflow.com/a/3233600/2016165
Недостатки этого (по сравнению с моимверсия не StorageVolume): а) вы не можете получить общее количество файлов в zip и б) также не можете получить (общий) размер файлов, а это означает, что вы не можете установить индикатор выполненияв диалоговом окне «Распаковка ...», если сначала вы не перебираете все записи zip для их подсчета.