key words : POI java讀取Excel?
java.io.IOException Unable to read entire block版本:2.5.1final
錯誤提示:
java.io.IOException Unable to read entire block
出這個問題具有隨機性,有時候沒問題,有時候將Excel里的CellType改一下好像就沒問題,但也不總是這樣,真是莫名其妙.
Google了一下是一個bug,重新下載src文件,將RawDataBlock.java文件的RawDataBlock(final InputStream stream)constructor覆蓋:
public?RawDataBlock(final?InputStream?stream)?throws?IOException
????{
????????_data?=?new?byte[?POIFSConstants.BIG_BLOCK_SIZE?];
????????int?count?=?0;
????????int?totalBytesRead?=?0;
????????while?((totalBytesRead?<?POIFSConstants.BIG_BLOCK_SIZE)?&&
(count?!=?-1))?{
????????????????count?=?stream.read(_data,?totalBytesRead,
POIFSConstants.BIG_BLOCK_SIZE?-?totalBytesRead);
????????????????if?(count?!=?-1)?{
????????????????????????totalBytesRead?+=?count;
????????????????}
????????}
??????????if?(count?==?-1)?{
????????????????_eof?=?true;
??????????}?else?{
????????????_eof?=?false;
????????}?
??????????if?((totalBytesRead?!=?POIFSConstants.BIG_BLOCK_SIZE)?&&?(totalBytesRead?!=?0))?{
????????????String?type?=?"?byte"?+?((totalBytesRead?==?1)???(""):?("s"));
????????????throw?new?IOException("Unable?to?read?entire?block;?"?+
totalBytesRead?+?type?+?"?read;?expected?"?+?POIFSConstants.BIG_BLOCK_SIZE?+?"bytes");
????????}
????}
打包:
ant?jar
重啟app,OK!
說明:
主要問題出在 InputStream的read上,原來的實現用ReadFully方法:public?static?int?readFully(InputStream?in,?byte[]?b,?int?off,?int?len)
????throws?IOException
????{
????????int?total?=?0;
????????for?(;;)?{
????????????int?got?=?in.read(b,?off?+?total,?len?-?total);
????????????if?(got?<?0)?{
????????????????return?(total?==?0)???-1?:?total;
????????????}?else?{
????????????????total?+=?got;
????????????????if?(total?==?len)
????????????????????return?total;
????????????}
????????}
????}
InputStream的read不能確保返回的是最大字節數,但是另一個實現卻可以:ByteInputStream
所以,下面的方法也可以修改這個問題:
?//?read?entire?stream?into?byte?array:
????ByteArrayOutputStream?byteOS?=?new?ByteArrayOutputStream();
????byte[]?buffer?=?new?byte[1024];
????int?count;
????while?(count?=?inputStream.read(buffer))?!=?-1)
????????byteOS.append(buffer,?0,?count);
????byteOS.close();
????byte[]?allBytes?=?byteOS.betByteArray();
//?create?workbook?from?array:
InputStream?byteIS?=?new?ByteArrayInputStream(allBytes);
HSSFWorkbook?wb?=?new?HSSFWorkbook(byteIS);