Android: read a GZIP file in the ASSETS folder
Solution 1
I met the same problem when reading a gz file from assets folder.
It's caused by the file name of the gz file. Just renaming yourfile.gz to other name like yourfile.bin. It seems Android build system would decompress a file automatically if it thought it's a gz.
Solution 2
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 is a zip file - this class will decompress all files in that zip to your local folder. I use this for NDK.
you can access your fils from ndk through: /data/data//files/
package = package where ResLoader resides filename = one of files that is in raw/resources.zip
Solution 3
this is the documented behavior of 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.
abusing available is a common mistake --- in no case can you assume that it tells you the length of a file (though it sometimes happens to do so, as you've noticed). you want to keep calling read(byte[], int, int) until it returns 0. if you want the length to allocate a byte[] up front, you probably want to create a ByteArrayOutputStream and write to that each time you read, and then get a byte[] from that when you exit the loop. this works for all InputStreams in all cases.
Solution 4
It seems that the build system treats .gz files as a special case, even when it's included as a raw resource. Rename the .gz file to have a different extension, say .raw or .bin .
Valid at least for Android Studio 2.2 . I can't find any docs to confirm this is expected behaviour or, better, how to prevent it, but changing the extension at least works around the problem.
Tawani
Updated on June 25, 2022Comments
-
Tawani about 2 years
How can you read GZIP file in Android located in the "ASSETS" (or resources/raw) folder?
I have tried the following code, but my stream size is always 1.
GZIPInputStream fIn = new GZIPInputStream(mContext.getResources().openRawResource(R.raw.myfilegz)); int size = fIn.available();
for some reason the size is always 1. But if Idon't GZIP the file, it works fine.
NOTE: Using Android 1.5
-
Tawani over 14 yearsI keep getting a FileNotFoundException which is ridiculus because the Resources know the file is there is R.raw.myfile
-
snctln over 14 yearshmmm, that is an odd problem. It's a shot in the dark but maybe try refreshing your project in eclipse and recompiling as described on stackoverflow.com/questions/2322820/…
-
Ted Hopp almost 13 yearsActually, it doesn't decompress the file; it just strips off the
.gz
extension. You still would need to wrap the input stream in a GZIPInputStream to read it. -
Pasi Matalamäki almost 6 yearsStill happens on newest Android Studio.. :P