使用 FileOutputStream 写入后无法删除文件
Cannot delete file after writing using FileOutputStream
我有 RESTful Web 服务,它具有上传文件的功能。它运行良好,但我的问题是当我尝试在 Windows 中手动删除上传的文件时,它说该文件已被使用。
要删除这些文件,我需要停止 Glassfish 服务器。我担心的是内存使用情况,当用户继续上传许多大文件时,这种未管理的代码可能会导致一些问题。我已经关闭了 InputStream
和 FileOutputStream
变量。请看下面的代码我不知道我错过了什么。
@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;
}
您已将 FileOutputStream out
初始化两次:第二次分配发生后,第一个创建的流将作为 non-referenced 对象保留在内存中,直到发生垃圾回收。由于服务器没有停止,可能内存负载不太高,垃圾收集器不收集垃圾,这就是为什么你不能从 Windows.
中删除它的原因
我有 RESTful Web 服务,它具有上传文件的功能。它运行良好,但我的问题是当我尝试在 Windows 中手动删除上传的文件时,它说该文件已被使用。
要删除这些文件,我需要停止 Glassfish 服务器。我担心的是内存使用情况,当用户继续上传许多大文件时,这种未管理的代码可能会导致一些问题。我已经关闭了 InputStream
和 FileOutputStream
变量。请看下面的代码我不知道我错过了什么。
@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;
}
您已将 FileOutputStream out
初始化两次:第二次分配发生后,第一个创建的流将作为 non-referenced 对象保留在内存中,直到发生垃圾回收。由于服务器没有停止,可能内存负载不太高,垃圾收集器不收集垃圾,这就是为什么你不能从 Windows.