Reputation: 3255
I want to read a zip file with java.util.zip.ZipFile
with android DocumentFile
Illustration:
With Storage Access Framework, I get the uri of a file in the android system and create a Documentfile with it. The document file is a folder that has a zip file "data.zip"
Data.zip has over 80 entries consisting of both text files and media file( >= 8mb <= 20mb). So, zip file is over 932mb.
With the filePAth, I can read an entry directly with the snippet below :
zipFile = new ZipFile(zipPath);
ZipEntry zipEntry = zipFile.getEntry(name);
if (zipEntry != null) {
return writeByteArraysToFile(ByteStreams.toByteArray(zipFile.getInputStream(zipEntry)), ext);
}
This works great on devices that does not required Storage access Framework.
For Devices that uses SAF, I am using a DocumentFile and I have reading the content like this :
InputStream inputStream = context.getContentResolver().openInputStream(documentFile.getUri());
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
ZipInputStream zipInputStream = new ZipInputStream(bufferedInputStream);
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
Log.e("field", entry.getName());
if (entry.getName().contains(name)) {
File file = PBUtils.writeByteArraysToFile(ByteStreams.toByteArray(zipInputStream), ext);
zipInputStream.closeEntry();
inputStream.close();
zipInputStream.close();
bufferedInputStream.close();
return file;
}
zipInputStream.closeEntry();
}
inputStream.close();
Not This Works, But here's the problem:
I need solutions on how I can make this faster and need to know if there's any way I can use ZipFile with DocumentFile so I can at least do something like this:
zipFile = new ZipFile(documentFileUri);
ZipEntry zipEntry = zipFile.getEntry(name);
if (zipEntry != null) {
return writeByteArraysToFile(ByteStreams.toByteArray(zipFile.getInputStream(zipEntry)), ext);
}
Upvotes: 7
Views: 1294
Reputation: 14755
With android DocumentFile
you have to use java.util.zip.ZipInputStream
or java.util.zip.ZipOutputStream
instead of java.util.zip.ZipFile
that can be used with android context.getContentResolver().openOutputStream()
and context.getContentResolver().openInputStream()
Upvotes: 1
Reputation: 5822
It's really a bummer - Google is force-feeding us unwanted Scope Storage, but not providing means to work with it where needed. One way to do this:
// mDocFile is a DocumentFile..., you also need a context (activity, service, app...
String getDocReadableFilePath(DocumentFile mDocFile, Context context) {
if (mDocFile != null && mDocFile.isFile()) {
try {
ParcelFileDescriptor parcelFileDescriptor =
context.getContentResolver().openFileDescriptor(mUri, "r"); // gets FileNotFoundException here, if file we used to have was deleted
if (parcelFileDescriptor != null) {
int fd = parcelFileDescriptor.detachFd(); // if we want to close in native code
return "/proc/self/fd/" + fd;
}
}
catch (FileNotFoundException fne) {
return "";
}
}
}
// Now you may use:
String documentFilePath = getDocReadableFilePath(docFile, context);
ZipFile zf = new ZipFile(documentFilePath);
Upvotes: 2