fatiDev
fatiDev

Reputation: 5992

could not delete file neither via java nor manually

I have the following situation, within a servlet a create a file and then have to delete it. When executing the file, I figured out that the file is still in the server, so I tried to remove it manually, I can't, I get the following message :

this file is opened by another program : javaw.exe

Here is my code :

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

Upvotes: 0

Views: 369

Answers (6)

gigadot
gigadot

Reputation: 8969

Whenever you open a file handler, you should close it. In a Java application that you want to run for a long period of time, you are strongly recommended to close all unused file handlers soon after you finish working with them.

Examples of common file handlers are FileOutputStream and FileInputstream. Here is a good example of how you open and close the 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();
    }
}

You should never do this:

doc.write( new FileOutputStream(temp));

because you can never close the file handler if it has no refernce to it.

Upvotes: 1

Zaw Than oo
Zaw Than oo

Reputation: 9935

For IO features, I would to suggest to use some kind of jar already provided by community. For example, 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);

good luck!

Upvotes: 1

helios
helios

Reputation: 13841

The problem is you are creating a new FileOutputStream(tempName) to write on that file, but never closing that outputstream (or another outputstream linked to it).

Do this:

FileOutputStream fos = newFileOutputStream(tempName);
// use it
fos.close(); // CLOSE IT!!

// then you can delete the file

Simplify

Maybe you could do the work another way, without temp files...

by example: doc.write(new FileOutputStream(tempName)) could be replaced by:

doc.write(response.getOutputStream());

This way doc sends its bytes directly to where you need them, not to a temp file eliminating the need for it.

The idea behind input/output streams is composing them. Input/OutputStream are the abstract base classes. And there are a lot of implementations:

  • based on memory: ByteArrayInput/OutputStream
  • based on files: FileInputOutputStream
  • compressing/decompressing to another outputstream: GZipInputOutputStream
  • and so on

The beauty of it is applying decorator pattern to add functionality. By example:

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.

Upvotes: 2

Bax
Bax

Reputation: 4506

maybe you should try ProcMon to find out what process exactly holds the file opened

Upvotes: 1

Amit
Amit

Reputation: 388

Seems like, you are not closing the file(out), thus it remains with the thread of this action, which is restricting it to get deleted.

Hope it helps.

Upvotes: 1

Gabber
Gabber

Reputation: 5482

You should close all the file-reading object instances. Besides, if you can delete the file manually, you should close java and then delete it, javaw is the process that launches java outside the console.

Upvotes: 4

Related Questions