2015-04-20 48 views
0

如何從ACTION_OPEN_DOCUMENT_TREE Intent所選文件夾中的zipfile中讀取數據?如何從ACTION_OPEN_DOCUMENT_TREE Intent所選文件夾中的zip文件中讀取數據?

我的應用程序讓用戶通過ACTION_OPEN_DOCUMENT_TREE Intent選擇一個文件夾。 在該文件夾中,我將使用具有特定名稱的Zipfile。 目標是使用java.util.zip.ZipFile讀取Zipfile。

如何從onActivityResult中提供的URI(Folderinfo)實例化ZipFile與此特定的Zipfilename?

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 ? 

回答

1

我如何實例化一個ZipFile中與此特定Zipfilename從所提供的URI(Folderinfo)在onActivityResult?

你不能,因爲沒有文件,並且ZipFile需要一個文件。你只能得到一個InputStream,在ContentResolver上使用openInputStream(),並且只有當你得到一個Uri到你正在尋找的那個特定文件。

您的選項似乎是:

  • 使用ZipInputStream,它可以包裝一個InputStream

  • 找一些接受一個InputStream作爲輸入,並給你一個更好的API第三方庫

  • 將ZIP文件複製到應用程序的內部存儲部分,並使用ZipFile

+0

正如我寫的。我將在該文件夾中有一個用戶選擇的zip文件。那麼是否真的沒有機會基於Folder-URI在此已存在的文件上實例化ZipFile? –

+1

@ user1344545:As * I *寫道,**沒有文件**。 ACTION_OPEN_DOCUMENT_TREE不返回「文件夾URI」。它返回一個'Uri'給'DocumentProvider'想要的任何東西。沒有要求它映射到設備本身的某個目錄。 'DocumentProvider'爲特定文檔返回的'Uri'不必映射到設備本身的某個文件。例如,「DocumentProvider」可以由「雲」支持而不是由本地文件支持,或者這些文件可以位於提供者可以訪問但不可用的可移動媒體上。 – CommonsWare

+0

如果我用fileexplorer手動將一個zip文件「myzip.zip」移動到一個文件夾/ sdcard/myfolder /(這就是我的意思是已經有一個文件)。然後,我啓動應用程序並選擇文件夾/ sdcard/myfolder與ACTION_OPEN_DOCUMENT_TREE意圖,我看到文件「myzip.zip」。然後我期望該文件在那裏,我希望可以用API列出它。所以我也希望閱讀這個文件。但是,謝謝我將使用ZipInputStream –

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; 
} 
相關問題