|
最近在pc中測(cè)試j2me gzip的效率:
碰到了如下異常: java.io.IOException: Unexpected end of ZLIB input stream at com.tinyline.util.GZIPInputStream.if(+39) at com.tinyline.util.GZIPInputStream.for(+48) at com.tinyline.util.GZIPInputStream.read(+27) at com.tinyline.util.GZIPInputStream.read(+8) ...... java.lang.NullPointerException
at java.io.OutputStream.write(+4) ..... 上網(wǎng)搜索找到如下文章,對(duì)我有所啟示,畢竟按照它的改法,在pc中,在手機(jī)中都o(jì)k了。 見 : http://hi.baidu.com/bobylou/blog/item/1f8600e91de9ee3cb90e2de6.html [第一篇]: java.io.EOFException: Unexpected end of ZLIB 的臨時(shí)解決方法 2007-12-01 04:09 bobrow小作,允許自由轉(zhuǎn)帖,不過(guò)請(qǐng)注明作者和出處,謝謝。 在玩httpunit1.6時(shí),捕獲了“java.io.EOFException: Unexpected end of ZLIB”異常。
問(wèn)題是這樣的,com.meterware.httpunit.WebResponse類的readFromStream方法中有一段讀取inputStream的代碼: if (maxBytes > 0) { do { outputStream.write( buffer, 0, count ); maxBytes -= count; if (maxBytes <= 0) break; count = inputStream.read( buffer, 0, Math.min( maxBytes, buffer.length ) ); } while (count != -1); } 拋出異常的正是做紅色標(biāo)記的代碼。由于拋出異常的前一個(gè)count值不是-1,所以執(zhí)行了紅色代碼。跟蹤進(jìn)去,發(fā)現(xiàn)java.util.zip.InflaterInputStream類方法fill(): protected void fill() throws IOException { ensureOpen(); len = in.read(buf, 0, buf.length); if (len == -1) { throw new EOFException("Unexpected end of ZLIB input stream"); } inf.setInput(buf, 0, len); } 因len為-1所以拋出異常。 按照我自己的理解,len為-1之前count肯定也為-1。但是實(shí)際執(zhí)行過(guò)程卻是count不為-1(表示inputStream還有后續(xù)內(nèi)容),但是len為-1(表示in沒(méi)有后續(xù)內(nèi)容了),這是矛盾的嘛。我還沒(méi)深入查看inputStream是怎么轉(zhuǎn)為fill()方法中in的。 知道問(wèn)題大概所在,我采取了很沒(méi)技術(shù)含量的方法:catch fill()方法拋出的IOException,然后在catch中把count置-1。代碼如下:
if (maxBytes > 0) { do { outputStream.write( buffer, 0, count ); maxBytes -= count; if (maxBytes <= 0) break; try { count = inputStream.read( buffer, 0, Math.min( maxBytes, buffer.length ) ); } catch (IOException e) { count = -1; } } while (count != -1); } 這樣count和len就保持一致了。但問(wèn)題來(lái)了:事實(shí)上inputStream還沒(méi)讀完的,所以WebResponse.getText()只有前半段內(nèi)容,會(huì)比瀏覽器里查看時(shí)內(nèi)容要少。這個(gè)很容易理解。 到現(xiàn)在我還不明白為什么明明count不為-1但是fill()方法卻不能讀流了呢?呵呵,繼續(xù)研究。
真正解決方法在這里。
[第二篇]:
httpunit中java.io.EOFException: Unexpected end of ZLIB 的解決方法
2007-12-01 14:28 bobrow小作,允許自由轉(zhuǎn)帖,但請(qǐng)注明出處和作者。謝謝。 今天凌晨寫了一篇暫時(shí)解決httpunit異常“java.io.EOFException: Unexpected end of ZLIB ”的方法,今天起床仔細(xì)查看了httpunit1.6的WebResponse代碼,在其defineRawInputStream方法中看到了感覺(jué)多于的代碼:
final protected void defineRawInputStream( InputStream inputStream ) throws IOException {
if (_inputStream != null || _responseText != null) { throw new IllegalStateException( "Must be called before response text is defined." ); } if (encodedUsingGZIP()) {
byte[] compressedData = readFromStream( inputStream, getContentLength() ); _inputStream = new GZIPInputStream( new ByteArrayInputStream( compressedData ) ); } else { _inputStream = inputStream; } } 紅色標(biāo)記的兩行代碼是其原有的代碼。把一個(gè)InputStream轉(zhuǎn)型為GZIPInputStream不需要這么復(fù)雜吧?
于是我把代碼一修改成如下:
final protected void defineRawInputStream( InputStream inputStream ) throws IOException {
if (_inputStream != null || _responseText != null) { throw new IllegalStateException( "Must be called before response text is defined." ); } if (encodedUsingGZIP()) {
_inputStream = new GZIPInputStream(inputStream); } else { _inputStream = inputStream; } } 藍(lán)色標(biāo)記代碼為我修改的。呵呵,問(wèn)題解決了。
后記:
1、其實(shí)為什么原代碼處理GZIP流時(shí)會(huì)出錯(cuò),而采用GZIPInputStream自帶轉(zhuǎn)型方式?jīng)]問(wèn)題,我也不是很明白,因?yàn)闆](méi)去看GZIPInputStream到底是怎么轉(zhuǎn)型的。得出的經(jīng)驗(yàn)就是標(biāo)準(zhǔn)庫(kù)有的方法,自己沒(méi)必要去再實(shí)現(xiàn)一遍。
2、昨晚搜索了Google和百度N多文章,將近兩小時(shí)的搜索也沒(méi)有這個(gè)問(wèn)題的結(jié)果。別人碰到過(guò)這個(gè)問(wèn)題,但就是沒(méi)人給出明確的解決方法。郁悶,只好自己動(dòng)手解決了。
自己剛開始用的出錯(cuò)的方法:
public static byte[] gzipToXmlBytes(byte[] zipedfilebytes) {
ByteArrayInputStream bis = new ByteArrayInputStream(zipedfilebytes); GZIPInputStream gis = null ; try { pos += "f" ; byte[] buf = new byte[BUFSIZE]; gis = new GZIPInputStream(bis); int len = 0; int realsize=0; while ( (len = gis.read(buf)) >= 0) { ......... ......... .........
后來(lái)按照上面的提示,問(wèn)題搞定了。
在手機(jī)上測(cè)試j2me gzip的解壓表現(xiàn):
把 a.gz文件[2.11M] 解壓到手機(jī)[n6120c]文件系統(tǒng)里面,大概需要23秒鐘左右.
解壓后的文件為a.dat文件[2.23M]。 把 b.gz文件[423k] 解壓到手機(jī)[n6120c]文件系統(tǒng)里面,大概需要5秒鐘左右. 解壓后的文件為b.dat文件[469k]。 大概平均一秒鐘 80~90k . 不知道其它仁兄的結(jié)果如何? 本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/xiaoli_feng/archive/2008/03/27/2223361.aspx |
|
|