2010-03-02 209 views
4

如何閱讀位於「ASSETS」(或resources/raw)文件夾中的Android中的GZIP文件?Android:在ASSETS文件夾中讀取GZIP文件

我曾嘗試下面的代碼,但我流的大小總是1.

GZIPInputStream fIn = new GZIPInputStream(mContext.getResources().openRawResource(R.raw.myfilegz)); 
int size = fIn.available(); 

由於某種原因,大小總是1.但是,如果。我不GZIP文件,它工作正常。

注: 採用了Android 1.5

+0

你檢查了你的文件大小嗎?由於APK文件是ZIP壓縮文件,如果該資源被壓縮,也許在GZIPping中沒有任何價值。 – CommonsWare 2010-03-02 15:54:43

+0

回聲commonsware,我發現gzipping資產已經完全沒有影響apk的大小,因爲apk的已壓縮。仍然有一個有趣的問題,爲什麼這不起作用(因爲在我的測試過程中,我已經獲得了這樣一個場景以便運行)。 – 2010-03-02 15:56:04

+1

int size = fIn.available(); < - java文檔說:EOF達到後返回0,否則總是返回1. – fazo 2010-03-07 19:24:31

回答

0

如果你使用AssetManager代替Resources發生什麼呢?例如:

InputStream is = mContext.getAssets().open("myfilegz"); 
GZIPInputStream fIn = new GZIPINputStream(is); 

在內部,Resources只是主叫AssetManager;我想知道是否在某個地方發生了事情。

0

嘗試看apps-for-android開源項目source for Translate,看看是否有幫助。

他們在他們的selectRandomWord使用GZIPInputStream上的原始文件()函數[線路326](以下源粘貼)

public void selectRandomWord() { 
    BufferedReader fr = null; 
    try { 
     GZIPInputStream is = 
       new GZIPInputStream(getResources().openRawResource(R.raw.dictionary)); 
+0

我不斷收到一個FileNotFoundException,這是一個嘲諷,因爲Resources知道文件存在是R.raw.myfile – Tawani 2010-03-02 19:40:37

+0

hmmm,這是一個奇怪的問題。這是在黑暗中拍攝,但也許嘗試刷新您的項目在日食和重新編譯描述http://stackoverflow.com/questions/2322820/update-jar-used-by-android-app-in-eclipse/ – snctln 2010-03-02 19:56:52

2

這是InflaterInputStream.available的記錄的行爲:

http://java.sun.com/javase/6/docs/api/java/util/zip/InflaterInputStream.html#available()

Returns 0 after EOF has been reached, otherwise always return 1. 

濫用可用是一個常見的錯誤---在任何情況下,你都不能假設它告訴你一個文件的長度(雖然我正如你已經注意到的那樣,有時恰好這樣做)。你想繼續調用read(byte [],int,int),直到它返回0.如果你想要長度先前分配一個字節[],你可能想要創建一個ByteArrayOutputStream並在每次讀取時寫入,然後在退出循環時從中獲得一個字節[]。這適用於所有情況下的所有InputStream。

3
public class ResLoader { 

    /** 
    * @param res 
    * @throws IOException 
    * @throws FileNotFoundException 
    * @throws IOException 
    */ 

    static void unpackResources() throws FileNotFoundException, IOException { 
     final int BUFFER = 8192; 

     android.content.res.Resources t = TestingE3d.mContext.getResources(); 

     InputStream fis = t.openRawResource(R.raw.resources); 
     if (fis == null) 
      return; 

     ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis, 
       BUFFER)); 
     ZipEntry entry; 
     while ((entry = zin.getNextEntry()) != null) { 
      int count; 

      FileOutputStream fos = TestingE3d.mContext.openFileOutput(entry 
        .getName(), 0); 
      BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); 

      byte data[] = new byte[BUFFER]; 

      while ((count = zin.read(data, 0, BUFFER)) != -1) { 
       dest.write(data, 0, count); 
       // Log.v("NOTAG", "writing "+count + " to "+entry.getName()); 
      } 
      dest.flush(); 
      dest.close(); 
     } 
     zin.close(); 

    } 

} 

R.raw.resources是一個zip文件 - 該類將解壓縮該zip文件中的所有文件到本地文件夾。 我用這個用於NDK。

你可以從NDK通過訪問您的費爾: /數據/數據//文件/

包=包凡ResLoader所在 名=文件之一是在原始/ resources.zip

3

從資產文件夾中讀取gz文件時遇到同樣的問題。

這是由gz文件的文件名造成的。只需將yourfile.gz重命名爲其他名稱,如yourfile.bin即可。看起來Android構建系統會自動解壓文件,如果它認爲它是一個gz。

+1

其實,它不解壓文件;它只是去掉'.gz'擴展名。您仍然需要將輸入流封裝到GZIPInputStream中以讀取它。 – 2011-07-11 18:43:15

+0

非常感謝! – technophyle 2017-08-11 17:48:45

0

構建系統似乎將.gz文件視爲一種特殊情況,即使它包含爲原始資源。將.gz文件重命名爲具有不同的擴展名,例如.raw或.bin。

至少對於Android Studio 2.2有效。我找不到任何文件來確認這是預期的行爲,或者更好的是如何防止它,但改變擴展至少可以解決問題。