Search code examples
javarestweb-servicesinputstreamfileoutputstream

Cannot delete file after writing using FileOutputStream


I have RESTful Web Service where it has a function to upload file. It is working well but my problem is when I try deleting the uploaded file manually in Windows it says the file is already used.

To delete those files I need to stop the Glassfish server. My concern is the memory usage maybe this unmanage code will cause some issue when user keep uploading many and large files. I already close the InputStream and FileOutputStream variables. Please see below code I do not know what I am missing.

@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;
}

Solution

  • You have initialized your FileOutputStream out twice: as soon as the second assignment takes place, the first created stream remains in the memory as non-referenced object until garbage collection takes place. Since the server is not stopped and probably memory load is not too high and garbage collector doesn't collect the garbage that's why you cannot delete it from Windows.