最近写Web项目时遇到了一个问题,对服务器上某个文件进行了读写操作后。再次执行该操作时,struts2报错,引发异常:C:\Program Files\Apache Software Foundation\Tomcat 7.0\wtpwebapps\ReadingNotes\work\000000\share\Welcometmp.pdf (请求的操作无法在使用用户映射区域打开的文件上执行。)
既然是IOException,那么肯定问题出在IO环节。检查了很久,最后发现问题出在action中一段代码:
for (int i = 0; i < files.length; i++) {
PdfReader reader = new PdfReader(files[i]);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
这里PdfReader是com.itextpdf.text.pdf包中的类,这个类的构造函数可以接收一个File类型参数,因此会打开一个文件流。而使用完reader后,没有关闭reader,导致文件依然被占用,所以第二次执行操作的时候就会引发IOException异常了。
解决办法:循环结束后关闭reader。
在循环后加上一行代码: reader.close();
for (int i = 0; i < files.length; i++) {
PdfReader reader = new PdfReader(files[i]);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
reader.close();
}
启示:不管是什么流,打开之后都要记得关闭,否则很容易引发异常。
关闭流时,也要注意流关闭的顺序:
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。