前段时间有一个客户遇到了一件很奇怪的事情,他在使用程序解析一批word文件时,程序在运行一段时间后总是会自动中断,他查看了导致中断的word文档,发现也能正常打开,当他把文件另存为后,再运行程序发现程序就可以正常往下运行了他感觉很奇怪,就找我来帮他分析一下原因,今天小编就来说说关于java基础入门第2版课后答案详解 java解析docdocx内容踩坑日记?下面更多详细答案一起来看看吧!

java基础入门第2版课后答案详解 java解析docdocx内容踩坑日记

java基础入门第2版课后答案详解 java解析docdocx内容踩坑日记

前段时间有一个客户遇到了一件很奇怪的事情,他在使用程序解析一批word文件时,程序在运行一段时间后总是会自动中断,他查看了导致中断的word文档,发现也能正常打开,当他把文件另存为后,再运行程序发现程序就可以正常往下运行了。他感觉很奇怪,就找我来帮他分析一下原因。

一、问题分析(以下日志和代码均是重现问题后输出的)

首先登录服务器,找到程序的运行日志,打开当天运行的日志文件,查看是否有错误日志,果然发现了错误日志,具体内容如下:

java.lang.IllegalArgumentException: The document is really a OOXML File at org.apache.poi.hwpf.HWPFDocumentCore.verifyAndBuildPOIFS(HWPFDocumentCore.java:123) at org.apache.poi.hwpf.extractor.WordExtractor.<init>(WordExtractor.java:51) at com.file.util.readword.redWordText(Test.java:25) at com.file.util.readword.main(Test.java:77)

根据错误日志不难分析出是解析doc文件报错了,根据错误日志可以直接定位到错位代码所在位置,通过反编译工具可以查看它的源码,源码具体如下(看到下面的代码,小伙伴们是否确定了问题的原因了?):

public static String redWordText(String filePath) { File file=new File(filePath); String fileName=file.getName();//获取文件名 String suffix = fileName.substring(fileName.indexOf("."), fileName.length());//获取文件后缀 String text=""; InputStream is = null; try { is = new FileInputStream(filePath); if (StringUtils.equals(suffix, ".doc")) {// 解析doc文件 WordExtractor ex = new WordExtractor(is); text = ex.getText(); ex.close(); } else if (StringUtils.equals(suffix, ".docx")) {// 解析docx文件 XWPFDocument doc = new XWPFDocument(is); XWPFWordExtractor extractor = new XWPFWordExtractor(doc); text = extractor.getText(); extractor.close(); } } catch (Exception e) { e.printStackTrace(); }finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return text; }

当我看到源码后,基本确定了问题出现的原因。

二、原因分析

客户收集上来的文件,渠道是多样的,有些docx文件的后缀被强制修改成了doc后缀,这些修改后的文件还是可以正常打开的。当使用StringUtils.equals(suffix, ".doc")这种直接判断后缀的方式来判断文件类型是返回true的,导致docx文件使用了doc的解析方式,所以报错了。

三、解决办法

针对上面的问题可以使用FileMagic.valueOf(is) == FileMagic.OLE2来判断是否是doc格式文件,具体实现代码如下:

public static String redWordText1(String filePath) { String text = ""; InputStream is = null; try { is = new FileInputStream(filePath); if (FileMagic.valueOf(is) == FileMagic.OLE2) { WordExtractor ex = new WordExtractor(is); text = ex.getText(); ex.close(); } else if (FileMagic.valueOf(is) == FileMagic.OOXML) { XWPFDocument doc = new XWPFDocument(is); XWPFWordExtractor extractor = new XWPFWordExtractor(doc); text = extractor.getText(); extractor.close(); } } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return text; }

四、其他存在的问题

当客户收集的文件的后缀被改成了大写,这种直接判断后缀的方法就无法判断了,需要在判断前把后缀统一成小写。

五、总结

通过上面的分析,小伙伴们以后判断word、excel文件格式时,一定要注意尽量避免直接使用后缀直接判断,推荐使用org.apache.poi.poifs.filesystem.FileMagic类进行判断(ps:专业的事情交给专业的来处理),否则一不小心就挖坑,导致后面的小伙伴又得加班填坑了。#头号有新人#

,