Let's explain it first
我正在使用webView加载HTML应用 . 为了保护源(脚本小子保护)我想从(受保护的)zip文件加载html代码 . html代码已经打包,缩小,组合等,所以大小只有700kb(解压缩) . 这很好用,但有一个问题,它有点慢 .
在下面的示例中,我从zip读取html文件并将结果放在一个字符串中 . 该字符串将用于通过使用以下代码将html代码加载到 webview
:
this.webView.loadDataWithBaseURL("file:///android_asset/", this.unzipStream(sFileName), "text/html", "UTF-8", "");
我已经使用不同的解决方案来加快速度并找出 bottleneck is at reading the contents from the zip. I increased the read buffer's blocksize but doesn't help, it never reads the full blocksize. 例如,当我使用4096字节(4kb)作为块大小时,它一次只能读取700到1100个字节 .
Question(s):
-
如何强制read函数使用指定的完整块大小?
-
否则,是否有另一种更好的方法(例如将其直接放入webview)?
这是我做的代码:
public String unzipStream( String sFileName )
{
final int BLOCKSIZE = 4096;
//String sResult = "";
long iSize = 0;
int iReaded = 0;
ByteArrayOutputStream sb = new ByteArrayOutputStream();
try {
InputStream is = this.activity.getAssets().open( sFileName );
BufferedInputStream fin = new BufferedInputStream( is );
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze;
while( (iSize == 0) && ((ze = zin.getNextEntry()) != null) && !ze.isDirectory() )
{
byte data[] = new byte[BLOCKSIZE];
long iTotal = ze.getSize();
while ((iReaded = zin.read(data,0,BLOCKSIZE)) > 0 && ((iSize+=iReaded) <= iTotal) )
{
sb.write(data,0,iReaded);
}
zin.closeEntry();
}
zin.close();
}
catch(Exception e)
{
System.out.println("Error unzip: "+e.getMessage());
//sResult = "";
iSize = 0;
}
if( iSize > 0 )
{
//Base64.
try {
return sb.toString("UTF-8");
//sResult = new String( Base64.decode(sb.toString("UTF-8"), Base64.DEFAULT), Charset.forName("UTF-8") );
}
catch(Exception ee)
{
//sResult = "";
}
}
return "";
}
Maybe another way to do it:
还发现了这个java zipfile类http://www.lingala.net/zip4j/ . 它使处理(密码保护)的zip文件更容易,但不包括一个函数(至少我认为是这样)将其解压缩为字符串 . 在搜索时找不到任何东西 . 这个课程无论如何都可能吗?
3 回答
之后, Headers 可能是“ZipInputStream限制读取性能”或类似的 Headers ,因为其他类型的流不限制读取大小 . 如果要获得4096个字节,则将获得4096个字节 . 例如,使用文本文件对此进行测试 . 我仍然不知道为什么ZipInputStream会限制读取性能 .
我'm not really sure there is a real performance boost (sometimes it is and sometimes not), but using now IOUtils from apache' s 'Commons IO'包 - http://commons.apache.org/proper/commons-io/ . 这也简化了整个'operation' .
我也看到了一些带有通道的解决方案,但似乎只能使用文件流,所以不能使用它(或者无法弄清楚如何将它应用于这种情况) . 另请参阅:Faster way of copying data in Java?(参见接受的答案) .
这是我制作的新版本(将对象名称更改为有意义的名称):
使用shouldInterceptRequest而不是loadDataWithBaseUrl可能会获得较小的性能提升 . 那赢得了整个解压缩的全部内容 .
你使用它的方式是:
尝试设置流的内部缓冲区大小: