【问题标题】:Cannot delete file after writing using FileOutputStream使用 FileOutputStream 写入后无法删除文件
【发布时间】:2019-11-10 05:46:12
【问题描述】:

我有 RESTful Web 服务,它具有上传文件的功能。它运行良好,但我的问题是当我尝试在 Windows 中手动删除上传的文件时,它说该文件已被使用。

要删除这些文件,我需要停止 Glassfish 服务器。我担心的是内存使用情况,当用户不断上传许多大文件时,这个不受管理的代码可能会导致一些问题。我已经关闭了InputStreamFileOutputStream 变量。请看下面的代码我不知道我错过了什么。

@POST
@Path("upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public String upload(@FormDataParam("file") InputStream uploadedInputStream, 
        @FormDataParam("file") FormDataContentDisposition fileDetail, @Context HttpServletRequest request) {
    String json = "";
    FileOutputStream out = null;
    try {
        File dir = new File(new File(".").getCanonicalPath() + File.separatorChar + "incidentreport" + File.separatorChar + "uploaded" + File.separatorChar + deviceId);
        dir.mkdirs();
        String location = dir.getAbsolutePath() + File.separatorChar + fileDetail.getFileName();
        out = new FileOutputStream(new File(location));
        int read = 0;
        byte[] bytes = new byte[1024];
        out = new FileOutputStream(new File(location));
        while ((read = uploadedInputStream.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }

        com.incidentreport.model.File file = new com.incidentreport.model.File(fileDetail.getFileName(), false);
        //FLAG FILE AS UPLOADED
        Response response = file.uploaded(deviceId, device.getId(), Util.toSqlTimestamp(dateUtc, "yyyy-MM-dd HH:mm:ss"));
        //DELETE UPLADED FILE IF FLAGGING NOT SUCCEED
        if(response.getStatus() != Response.SUCCESS) new File(location).delete();
        json = new Gson().toJson(response);
    } catch (Exception ex) {
        Logger.getLogger(FileResource.class.getName()).log(Level.SEVERE, null, ex);
        json = new Gson().toJson(new Response(Response.ERROR, ex.getMessage()));
    } finally {
        try {
            uploadedInputStream.close();
            uploadedInputStream = null;
            out.flush();
            out.close();
            out = null;
        } catch (IOException ex) {
            Logger.getLogger(FileResource.class.getName()).log(Level.SEVERE, null, ex);
            json = new Gson().toJson(new Response(Response.WARNING, ex.getMessage()));
        }
    }
    return json;
}

【问题讨论】:

  • 您必须关闭finally 块中的流或(最好)在try-with-resources 语句中使用它们。
  • 我试过了,结果一样。
  • 你能发布一个更新的代码吗?
  • 您需要在尝试删除之前关闭FileOutputStream。 @DmitriyPopov 的建议只会让事情变得更糟。

标签: java rest web-services inputstream fileoutputstream


【解决方案1】:

你已经初始化了你的FileOutputStream out 两次:一旦第二次分配发生,第一个创建的流作为非引用对象保留在内存中,直到垃圾回收发生。由于服务器没有停止并且内存负载可能不是太高并且垃圾收集器不会收集垃圾,这就是您无法从 Windows 中删除它的原因。

【讨论】:

  • 哎呀..这很尴尬。这就是不建议复制粘贴的原因。是的,我现在可以在删除第二次初始化后删除该文件。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
相关资源
最近更新 更多