随笔-18  评论-7  文章-0  trackbacks-0
  POI的Unable to read entire block明显是已经久悬未决的问题了,至今在网上查找资料,都没有一个能确定解决的方案。上周在客户那里碰到这个问题,弄了4天,才算搞定。这个解决方式倒是没有发现有描述的,较为简单,而且还没有经过长时间测试,不敢保证能够彻底解决问题,但希望能给在泥潭中苦苦挣扎的朋友们提供一个思路。
  我的程序需要将加密的Doc文件先解密出来,存为一个临时的解码原文件,从这个原文件中抽取索引,再删除临时文件。这时候Unable to read entire block的问题就很明显。做了测试,如果直接拿原文件来抽取没问题,就是不经过加密、写出这步,并且确信加密解密不会造成文件的数据混乱或丢失,那么问题肯定是写出的文件和原文件不同咯。于是拿两个文件来对比,发现字节数不一样,如我的异常报的是Unable to read entire block;81 bytes read; expected 512 bytes ,两个文件之间差的字节数正是81byte。于是再用UE编辑器打开两个文件来比较,发现无法抽取的Doc文件最后部分比原文件多了81个0。
  查看代码,发现我的字节数组是这样定义的byte[] b = byte[255]; 每个字节数组块是255的大小,当文件写出到末尾时,会把初始化却没有用到的最后一批0一起写到文件中。偏偏POI以512为单位来读取,当读到Doc文档的末尾,发现还有字节,就报错,表示这个文件不正确。
  解决方式有两种,我同事使用的是将POI源码修改了,碰到多出来的字节不校验,直接通过,但是这样造成后面的字符串截取子串出问题,不能确保解决。另外一种就很简单了,将程序中所有的byte初始化定义成byte[512],这样定义的字节数组块跟POI读取的字节块是一致的,问题也随之解决了。

PS:另外,早在2006年的一篇资料(忘记原址了,sorry),已指出是用FileOutputStrem和FileInputStream输入输出的字节数不一致造成的,不过解决方案使用的是用ByteArrayInputStream来进行读取,难道ByteArrayInputStream能够将用不到的byte[]截取掉吗?没有验证过,但是照他的方式来修改也无法解决这个问题。最后还是用byte[512]的方式来解决的。先观察一段时间再说
posted on 2008-06-19 22:12 Timnity 阅读(5685) 评论(0)  编辑  收藏 所属分类: Tools

只有注册用户登录后才能发表评论。


网站导航: