我尝试了以下代码,但我的流大小总是1。
GZIPInputStream fIn = new GZIPInputStream(mContext.getResources().openRawResource(R.raw.myfilegz));
int size = fIn.available();
由于某些原因,文件的大小始终为1。但是如果不使用GZIP压缩文件,则可以正常工作。
注意: 使用Android 1.5版本。
GZIPInputStream fIn = new GZIPInputStream(mContext.getResources().openRawResource(R.raw.myfilegz));
int size = fIn.available();
由于某些原因,文件的大小始终为1。但是如果不使用GZIP压缩文件,则可以正常工作。
注意: 使用Android 1.5版本。
当我从资产文件夹读取gz文件时,遇到了同样的问题。
这是由于gz文件的文件名引起的。只需将yourfile.gz重命名为其他名称,例如yourfile.bin。如果Android构建系统认为它是gz文件,则似乎会自动解压缩文件。
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 访问您的文件: /data/data//files/
包名 = ResLoader 所在的包 文件名 = raw/resources.zip 中的文件之一
Returns 0 after EOF has been reached, otherwise always return 1.
滥用available是一个常见的错误 --- 你不能假设它告诉你文件的长度(尽管有时候会这样做,正如你所注意到的)。你需要不断调用read(byte[], int, int)直到它返回0。如果你想要预先分配一个byte[]的长度,你可能需要创建一个ByteArrayOutputStream,并在每次读取时写入它,然后在退出循环时从中获取一个byte[]。这对于所有InputStreams在所有情况下都适用。
至少在Android Studio 2.2中有效。我找不到任何文档来确认这是预期行为或更好的方法来防止它,但至少更改扩展名可以解决问题。
如果使用 AssetManager
而不是 Resources
,会发生什么?示例:
InputStream is = mContext.getAssets().open("myfilegz");
GZIPInputStream fIn = new GZIPINputStream(is);
Resources
只是调用了AssetManager
;我想知道是否在某个地方出现了问题。试着查看Translate的源代码和Android应用程序开源项目,看看是否有所帮助。
他们在selectRandomWord()函数[line 326]中使用GZIPInputStream来处理原始文件(以下是源代码)
public void selectRandomWord() {
BufferedReader fr = null;
try {
GZIPInputStream is =
new GZIPInputStream(getResources().openRawResource(R.raw.dictionary));