java - Android Java : Reading file from zip file into webview/string, 为什么ZipInputStream限制读取性能?

标签 java android zip android-webview unzip

我们先解释一下

我正在使用 webView 加载 HTML 应用程序。为了稍微保护源代码(脚本小子保护),我想从( protected )zip 文件加载 html 代码。 html 代码已经打包、缩小、组合等,因此大小仅为 700kb(未打包)。这工作得很好,但有一个问题,它有点慢。

在下面的示例中,我从 zip 中读取 html 文件并将结果放入字符串中。该字符串将用于通过以下代码将 html 代码加载到 webview 中:

this.webView.loadDataWithBaseURL("file:///android_asset/", this.unzipStream(sFileName), "text/html", "UTF-8", "");  

我尝试过不同的解决方案,以使其更快,并发现瓶颈在于读取 zip 中的内容。我增加了读取缓冲区的 block 大小,但没有帮助,它永远不会读取完整的 block 大小。例如,当我使用 4096 字节 (4kb) 作为 block 大小时,它一次只能读取 700 到 1100 字节。

问题:

  • 如何强制读取函数使用指定的完整 block 大小?
  • 否则,还有其他更好的方法吗(例如直接放入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 "";
      } 

也许还有另一种方法:

还发现了这个java zipfile类http://www.lingala.net/zip4j/ 。它使处理(受密码保护的)zip 文件变得更容易,但不包含将其解压缩为字符串的函数(至少我这么认为)。搜索时什么也没找到。这对于这个类来说是可能的吗?

最佳答案

之后,标题可能是“ZipInputStream 限制读取性能”或类似内容,因为其他类型的流不限制读取大小。当你想得到4096字节时,你就会得到4096字节。例如,使用文本文件对此进行了测试。我还是不明白为什么ZipInputStream会限制读取性能。

我不太确定是否有真正的性能提升(有时是,有时不是),但现在使用 apache 的“Commons IO”包中的 IOUtils - http://commons.apache.org/proper/commons-io/ 。这也简化了整个“操作”。

我还看到了一些带有 channel 的解决方案,但似乎只适用于文件流,因此无法使用它(或者无法弄清楚如何将其应用于这种情况)。 另请参阅:Faster way of copying data in Java? (参见已接受的答案)。

这是我制作的新版本(还将对象名称更改为有意义的名称):

public String unzipStream( String sFileName ) 
{ 
    ByteArrayOutputStream oBaosBuffer = new ByteArrayOutputStream(); 
    try  
    { 
      ZipInputStream oZipStream = new ZipInputStream( this.activity.getAssets().open( sFileName ) ); 
      ZipEntry oZipEntry;
      long iSize = 0;

      while( (iSize == 0) && ((oZipEntry = oZipStream.getNextEntry()) != null) && !oZipEntry.isDirectory() ) 
      {
           iSize = IOUtils.copyLarge(oZipStream, oBaosBuffer);
           oZipStream.closeEntry(); 
      } 

      oZipStream.close(); 

      if( iSize > 0 )
      {
        return oBaosBuffer.toString("UTF-8");
        //sResult = new String( Base64.decode(sb.toString("UTF-8"), Base64.DEFAULT), Charset.forName("UTF-8") );
      }
    } 
    catch(Exception e) 
    { 
         System.out.println("Error unzip: "+e.getMessage());
    } 

    return null;
} 

关于java - Android Java : Reading file from zip file into webview/string, 为什么ZipInputStream限制读取性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22259773/

相关文章:

android - Sqlite死锁问题

java - 读取 jar 文件中的 zip 文件

java - 这两个 Spring IOC 注入(inject)有什么区别?

java - 我如何解析单个变量中保存的每个字符串

android - Web 浏览器应用程序 facebook 的 Css 除外(hack)?

android - XML 解析给出 NullPointerException Error with Asynctask

java - 无法解析方法 'addToRequestQueque(com.android.volley.toolbox.StringRequest,java.lang.String)'

java - 从数据库访问和使用 .jsf 文件

unix - 如何使用 maven 解压缩符号链接(symbolic link)?

python - 如何使用 PIL/Pillow 读取 zip 文件中的图像