我有以下情况,在servlet中创建一个文件然后必须删除它。 执行文件时,我发现该文件仍然在服务器中,所以我尝试手动删除它,我不能,我收到以下消息:
此文件由另一个程序打开:javaw.exe
这是我的代码:
public class GenerateFile extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("ok");
String fileName = request.getParameter("fileName");
Integer nbrParam = Integer.parseInt(request.getParameter("nbrParam"));
String[] valueParam = new String[nbrParam+1];
for(int i =1;i<=nbrParam;i++)
{ System.out.println(request.getParameter("param"+i));
valueParam[i]=request.getParameter("param"+i);
}
FileInputStream in = new FileInputStream("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\"+fileName+".doc");
POIFSFileSystem fs = new POIFSFileSystem(in);
HWPFDocument doc = new HWPFDocument(fs);
Range r = doc.getRange();
for(int i=1;i<=nbrParam;i++)
{ System.out.println("<param"+i+">");
System.out.println(valueParam[i]);
r.replaceText("<param"+i+">", valueParam[i]);
}
File file = new File("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\temp");
File temp = File.createTempFile("monfile",".doc",file);
String tempName =temp.getName();
doc.write( new FileOutputStream(temp));
OutputStream out = response.getOutputStream();
response.setContentType("application/rtf");
response.setHeader("Content-Disposition","attachment; filename=Decision");
FileInputStream in1 = new FileInputStream(temp);
byte[] buffer = new byte[4096];
int length;
while ((length = in1.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in1.close();
out.flush();
System.out.println("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\temp\\"+tempName);
File f = new File("C:\\Users\\free\\Desktop\\myworkspace\\gestionRH\\WebRoot\\fiches\\temp\\"+tempName);
f.delete();
return null;
}
}
答案 0 :(得分:4)
您应该关闭所有文件读取对象实例。此外,如果你可以手动删除文件,你应该关闭java然后删除它,javaw是在控制台外启动java的过程。
答案 1 :(得分:2)
问题是你正在创建一个new FileOutputStream(tempName)
来写入该文件,但从不关闭该输出流(或与其链接的另一个输出流)。
这样做:
FileOutputStream fos = newFileOutputStream(tempName);
// use it
fos.close(); // CLOSE IT!!
// then you can delete the file
<强>简化强>
也许你可以用另一种方式完成工作,没有临时文件......
示例:doc.write(new FileOutputStream(tempName))
可以替换为:
doc.write(response.getOutputStream());
这样,doc会将其字节直接发送到您需要的位置,而不是临时文件,而不需要它。
输入/输出流背后的想法是组合它们。 Input / OutputStream是抽象基类。并且有很多实现:
它的美妙之处在于应用装饰模式来添加功能。例如:
new GZipOutputStream(new ByteArrayOutputStream());
// creates an outputstreams that compress data received and send it to the other stream
// the BAOS then writes the received bytes to memory
new GZipOutputStream(new FileOutputStream());
// it's the same but sending compressed bytes to a file.
答案 2 :(得分:1)
似乎,你没有关闭文件(out),因此它仍然是这个动作的线程,这限制了它被删除。
希望它有所帮助。
答案 3 :(得分:1)
也许您应该尝试ProcMon找出确切保存文件的过程
答案 4 :(得分:1)
对于IO功能,我建议使用社区已经提供的某种jar。 例如,common-io.x-x.jar,spring-core.jar
Eg, org.apache.commons.io.FileUtils;
FileUtils.copyDirectory(from, to);
FileUtils.deleteDirectory(childDir);
FileUtils.forceDelete(springConfigDir);
FileUtils.writeByteArrayToFile(file, data);
org.springframework.util.FileSystemUtils;
FileSystemUtils.copyRecursively(from, to);
FileSystemUtils.deleteRecursively(dir);
祝你好运!
答案 5 :(得分:1)
无论何时打开文件处理程序,都应该关闭它。在要运行很长一段时间的Java应用程序中,强烈建议您在使用完毕后立即关闭所有未使用的文件处理程序。
常见文件处理程序的示例包括FileOutputStream
和FileInputstream
。以下是打开和关闭FileOutputStream
FileOutputStream fos = null;
try {
fos = new FileOutputStream(tempName);
// do something
} catch (IOException ex) {
// deal with exceptions
} finally {
// close if fos is not null
if (fos != null) {
fos.close();
}
}
你永远不应该这样做:
doc.write( new FileOutputStream(temp));
因为如果文件处理程序没有引用它,你就永远无法关闭它。