0

我有以下情况,在 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;
    }
}
4

6 回答 6

4

您应该关闭所有文件读取对象实例。另外,如果你可以手动删除文件,你应该关闭java然后删除它,javaw是在控制台之外启动java的进程。

于 2012-09-17T10:50:28.780 回答
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 是抽象基类。并且有很多实现:

  • 基于内存:ByteArrayInput/OutputStream
  • 基于文件:FileInputOutputStream
  • 压缩/解压缩到另一个输出流:GZipInputOutputStream
  • 等等

它的美妙之处在于应用装饰器模式来添加功能。举例:

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.
于 2012-09-17T10:54:45.053 回答
1

似乎,您没有关闭文件(输出),因此它保留在此操作的线程中,这限制了它被删除。

希望能帮助到你。

于 2012-09-17T10:52:43.307 回答
1

也许您应该尝试使用 ProcMon来找出打开文件的确切进程

于 2012-09-17T10:54:03.450 回答
1

对于 IO 功能,我建议使用社区已经提供的某种 jar。例如common-io.xx.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);

祝你好运!

于 2012-09-17T11:01:13.880 回答
1

每当您打开文件处理程序时,都应该关闭它。在您想要长时间运行的 Java 应用程序中,强烈建议您在使用完所有未使用的文件处理程序后立即关闭它们。

常见文件处理程序的示例是FileOutputStreamFileInputstream。这是一个很好的例子,说明如何打开和关闭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));

因为如果没有引用文件处理程序,您将永远无法关闭它。

于 2012-09-17T11:02:45.803 回答