使用Android DocumentFile读取Zip文件

6
我想使用java.util.zip.ZipFile和Android的DocumentFile来读取一个zip文件。 说明: 通过Storage Access Framework,我获得了Android系统中一个文件的uri,并用它创建了一个Documentfile。这个documentfile是一个包含zip文件"data.zip"的文件夹。
"data.zip"中有80多个条目,包括文本文件和媒体文件(>= 8mb <= 20mb)。因此,zip文件大小超过了932MB。
通过文件路径,我可以使用以下代码片段直接读取一个条目:
zipFile = new ZipFile(zipPath);
                ZipEntry zipEntry = zipFile.getEntry(name);
                if (zipEntry != null) {
                    return writeByteArraysToFile(ByteStreams.toByteArray(zipFile.getInputStream(zipEntry)), ext);
                }

对于不需要存储访问框架(Storage Access Framework)的设备,这很有效。

对于使用SAF的设备,我正在使用一个DocumentFile,并按以下方式读取内容:

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();

虽然这个程序可以工作,但是存在以下问题:

  1. 当迭代条目以查找特定条目时,速度较慢。我进行了调试并发现读取媒体条目所需的时间导致了延迟。

我需要解决方案,以使其更快,并且需要知道是否有办法将ZipFile与DocumentFile一起使用,以便我至少可以做到这样:

zipFile = new ZipFile(documentFileUri);
                ZipEntry zipEntry = zipFile.getEntry(name);
                if (zipEntry != null) {
                    return writeByteArraysToFile(ByteStreams.toByteArray(zipFile.getInputStream(zipEntry)), ext);
                }
2个回答

2

真是个烦心事 - Google强制使用不需要的Scope Storage,但却没有提供必要的手段在需要时与其交互。一种解决方法如下:

    // 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);

这会返回(权限被拒绝) - Gil SH

1
使用Android的DocumentFile,您需要使用java.util.zip.ZipInputStreamjava.util.zip.ZipOutputStream,而不是java.util.zip.ZipFile,后者可以与Android的context.getContentResolver().openOutputStream()context.getContentResolver().openInputStream()一起使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接