【问题标题】:how to read from a zipfile in a folder which was selected by the ACTION_OPEN_DOCUMENT_TREE Intent?如何从 ACTION_OPEN_DOCUMENT_TREE Intent 选择的文件夹中的 zipfile 中读取?
【发布时间】:2015-04-20 11:42:28
【问题描述】:

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

我的应用让用户通过 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 ?

【问题讨论】:

    标签: android android-5.0-lollipop


    【解决方案1】:

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

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

    您的选择似乎是:

    • 使用ZipInputStream,可以包装InputStream

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

    • 将 ZIP 文件复制到应用的内部存储部分并使用 ZipFile 读取其内容

    【讨论】:

    • 正如我所写。我将在该文件夹中已经有一个用户选择的 zipfile。那么真的没有机会根据 Folder-URI 在这个已经存在的 File 上实例化一个 ZipFile 吗?
    • @user1344545:正如所写,没有文件ACTION_OPEN_DOCUMENT_TREE 不返回“文件夹 URI”。它将Uri 返回到DocumentProvider 想要的任何内容。不要求它映射到设备本身的某个目录。 DocumentProvider 为特定文档返回的 Uri 不必映射到设备本身的某个文件。例如,DocumentProvider 可以由“云”而不是本地文件支持,或者文件可能位于提供商可以访问但您不能访问的可移动媒体上。
    • 如果我使用文件资源管理器手动将 zip 文件“myzip.zip”移动到文件夹 /sdcard/myfolder/ (这就是我的意思是已经有一个文件)。然后我启动应用程序并选择带有 ACTION_OPEN_DOCUMENT_TREE Intent 的文件夹 /sdcard/myfolder ,我看到了文件 "myzip.zip" 。然后我希望文件在那里,我希望可以用 API 列出它。所以我也希望阅读这个文件。但是谢谢我会尝试使用 ZipInputStream
    • @user1344545 - 不,您的期望是错误的。不一定有任何实际的“文件”,即使有,根据位置的不同,它可能只能由某些 Android 内部守护程序访问,而不能直接由您的应用程序访问。 ZipInputStream 方法是您应该执行此操作的方式,因为它利用了这样一个事实,即虽然许多这些抽象不会向您公开实际的文件,但它们会给您一个 InputStream i> 通过实际在幕后的任何实现进行代理。
    • 谢谢克里斯。我已经实现了 CommonsWare 建议的 ZipInputStream 解决方案。我也接受了。
    【解决方案2】:

    我正在解决这个问题,最终采用了@CommonsWare 作为第三个选项提到的策略,即将文件复制到非 SD 卡位置并作为 ZipFile 加载。它运作良好,所以我将我的 sn-p 分享给大家。

     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;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-16
      • 2022-01-23
      • 1970-01-01
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 2015-02-06
      相关资源
      最近更新 更多