我有一个按钮,可为客户端生成docx文件。我遇到的问题是,将生成的文件提供给客户端后,我无法将其删除。服务器端技术是JSF(XPages)。该按钮将调用以下代码:
var v = new ru.generate.doc.generateDoc();
v.generateReport2();
generateReport2()
方法调用generateFromTemplateAndReturnPath(String template)
的2个重要方法:
private String generateFromTemplateAndReturnPath(String pathToTemplate)
{
XWPFDocument document = new XWPFDocument(OPCPackage.open(pathToTemplate));
String pathToFinalResult = FilenameUtils.getFullPath(pathToTemplate) + "reportTest.docx";
FileOutputStream fous = new FileOutputStream(pathToFinalResult);
document.write(fous);
fous.close();
return pathToFinalResult;
}
和将报告提供给客户的giveDocumentForClient(String pathToCompleteFile)
方法:
private void giveDocumentForClient(String pathToCompleteFile) throws InvalidFormatException, IOException
{
String fn = new File(pathToCompleteFile).getName();
XspHttpServletResponse response = (XspHttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setContentType(URLConnection.guessContentTypeFromName(fn));
response.setHeader("Content-disposition", "attachment; filename=" + fn);
OutputStream output = response.getOutputStream();
output.write(IOUtils.toByteArray(new FileInputStream(new File(pathToCompleteFile))));
output.close();
FacesContext.getCurrentInstance().responseComplete();
}
此方法完成后,我尝试在generateReport2()
内进行修改:
new File(pathToCompleteFile).delete()
无论我做什么,此方法都将返回false。我也尝试过:
FileDeleteStrategy.FORCE.delete(new File(pathToSubstitutedDoc))
但仍然没有结果。
诸如canRead(),canWrite(),canExecute()之类的方法始终返回true。 SecurityManager也会无例外地执行方法。问题是什么?
答案 0 :(得分:2)
嗯,这真的很简单。我忘记了FileInputStream也应该关闭。
方法应如下所示:
private void giveDocumentForClient(String pathToCompleteFile) throws InvalidFormatException, IOException
{
FileInputStream fis = new FileInputStream(new File(pathToCompleteFile));
String fn = new File(pathToCompleteFile).getName();
XspHttpServletResponse response = (XspHttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setContentType(URLConnection.guessContentTypeFromName(fn));
response.setHeader("Content-disposition", "attachment; filename=" + fn);
OutputStream output = response.getOutputStream();
output.write(IOUtils.toByteArray(fis));
output.close();
fis.close();
FacesContext.getCurrentInstance().responseComplete();
}
答案 1 :(得分:1)
您可以尝试更好的Files类:
OutputStream output = response.getOutputStream();
Files.copy(Paths.get(pathToCompleteFile), output);
Files.delete(Paths.get(pathToCompleteFile));
尽管这可能无法解决问题。
如果不可删除,则在生成文件时会 未关闭 。由于应用程序仍在运行,因此文件句柄得以维护。这尤其 Windows下可能就是这种情况。
(否则可能是文件权限问题。但是您检查了以下内容: SecurityManager 和 canRead 。)
然后有一些深奥的案例,例如病毒扫描程序。
查看生成的代码后;做
try (FileOutputStream fous = new FileOutputStream(pathToFinalResult)) {
document.write(fous);
} // Automatic fous.close() even on exception or return.
此try-with-resources确保自动关闭,即使在异常/中断/返回时也是如此。