如何从ACTION_OPEN_DOCUMENT_TREE Intent选择的文件夹中的zip文件中读取?

时间:2015-04-20 11:42:28

标签: android android-5.0-lollipop

如何从ACTION_OPEN_DOCUMENT_TREE Intent选择的文件夹中读取zipfile?

我的应用让用户通过ACTION_OPEN_DOCUMENT_TREE Intent选择一个文件夹。 在该文件夹中,我将有一个具有特定名称的Zipfile。 目标是用java.util.zip.ZipFile读取Zipfile。

如何使用onActivityResult中提供的URI(Folderinfo)中的特定Zipfilename实例化ZipFile?

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Uri treeUri = data.getData();
    String sPath=treeUri.getPath();

    java.util.zip.ZipFile myzip=new java.util.zip.ZipFile("mypath"); <-- Constructor expects File or Path as String. Howto handle this with the Uri ?

2 个答案:

答案 0 :(得分:1)

  

如何使用onActivityResult中提供的URI(Folderinfo)中的特定Zipfilename实例化ZipFile?

你不能,因为没有文件,ZipFile需要一个文件。您只能在InputStream上使用openInputStream()获得ContentResolver,并且只有在您获得所需的特定文件Uri时才能获得。{/ p >

您的选项似乎是:

  • 使用ZipInputStream,可以打包InputStream

  • 找一些接受InputStream作为输入的第三方库,为您提供更好的API

  • 将ZIP文件复制到应用程序的内部存储空间,并使用ZipFile

  • 阅读其内容

答案 1 :(得分:0)

我正在研究这个问题并最终采用@CommonsWare作为第三个选项提到的策略,即将文件复制到非sdcard位置并加载为ZipFile。它运作良好,所以我分享给每个人的代码片段。

 public static ZipFile loadCachedZipFromUri(Context context, Uri uri, String filename){
    File file = new File(context.getCacheDir(), filename);
    String fileName = context.getCacheDir().getAbsolutePath() + '/' + filename;
    ZipFile zip = null;

    if (file.exists()){
        Log.d(TAG, "file exists");
        try {
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // N for Nougat
                zip = new ZipFile(fileName, Charset.forName("ISO-8859-1"));

            }else{
                zip = new ZipFile(fileName);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return zip;
    }

    DocumentFile dest = DocumentFile.fromFile(file);

    InputStream in = null;
    OutputStream out = null;

    Log.d(TAG, "Copy started");
    try {
        in = context.getContentResolver().openInputStream(uri);
        out = context.getContentResolver().openOutputStream(dest.getUri());
        byte[] buf = new byte[2048];
        int len = 0;
        while((len = in.read(buf)) >= 0){
            out.write(buf, 0, len);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    Log.d(TAG, "Load copied file");
    try {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // N for Nougat
            zip = new ZipFile(fileName, Charset.forName("ISO-8859-1"));

        }else{
            zip = new ZipFile(fileName);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return zip;
}