tags:

views:

768

answers:

6

The problem is, user clicks a button in JSP, which will export the displayed data. So what i am doing is, creating a temp. file and writing the contents in it [ resultSet >> xml >> csv ], and then writing the contents to ServletResponse. After closing the respons output stream, i try to delete the file, but every time it returns false.

code;

public static void writeFileContentToResponse ( HttpServletResponse response , String fileName ) throws IOException{

     ServletOutputStream responseoutputStream = response.getOutputStream();
     File file = new File(fileName);
     if (file.exists()) {
      file.deleteOnExit();

      DataInputStream dis = new DataInputStream(new FileInputStream(
        file));

      response.setContentType("text/csv");
      int size = (int) file.length();
      response.setContentLength(size);
      response.setHeader("Content-Disposition",
        "attachment; filename=\"" + file.getName() + "\"");   
      response.setHeader("Pragma", "public");
      response.setHeader("Cache-control", "must-revalidate");

      if (size > Integer.MAX_VALUE) {

      }
      byte[] bytes = new byte[size];

      dis.read(bytes);
      FileCopyUtils.copy(bytes, responseoutputStream );
     }
     responseoutputStream.flush();
     responseoutputStream.close();
     file.delete();
    }

i have used 'file.deleteOnExit();' and file.delete(); but none of them is working.

A: 

You really don't want to create a temporary file for a request. Keep the resulting CSV in memory if at all possible.

You may need to tie the writing of the file in directly with the output. So parse a row of the result set, write it out to response stream, parse the next row and so on. That way you only keep one row in memory at a time. Problem there is that the response could time out.

If you want a shortcut method, take a look at Display tag library. It makes it very easy to show a bunch of results in a table and then add pre-built export options to said table. CSV is one of those options.

James McMahon
actually we were using DisplayTag earlier, but now it is avoided because of size limitation. I can't have **CSV** in memory, this might be very huge.
Rakesh Juyal
+3  A: 

file.deleteOnExit() isn't going to produce the result you want here - it's purpose is to delete the file when the JVM exits - if this is called from a servlet, that means to delete the file when the server shuts down.

As for why file.delete() isn't working - all I see in this code is reading from the file and writing to the servlet's output stream - is it possible when you wrote the data to the file that you left the file's input stream open? Files won't be deleted if they're currently in use.

Also, even though your method throws IOException you still need to clean up things if there's an exception while accessing the file - put the file operations in a try block, and put the stream.close() into a finally block.

Nate
even when server is shut down, the file still remains there
Rakesh Juyal
Is this on windows? I found a bug report - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4171239 - stating that on windows file.deleteOnExit() did not work if the file is still open when the JVM exits. Since file.delete() doesn't work - the file is still open in some way. I'm not sure about the status of this bug in the current JVM... it's marked as 'reported against' up to 1.3, but I don't see anything in the 'release fixed'... closed as a duplicate then, but don't see a fix in the bug it's a duplicate of either...
Nate
A: 

Don't create that file. Write your data directly from your resultset to your CSV responseoutputStream. That saves time, memory, diskspace and headache.

If you realy need it, try using File.createTempFile() method. These files will be deleted when your VM stops normaly if they haven't been deleted before.

Lars
If this is on the server side those temp files could really build up as the JVM is always running.
James McMahon
A: 

How are you creating the file. You probably need to use createTempFile.

You should be able to delete a temporary file just fine (No need for deleteOnExit). Are you sure the file isn't in use, when you are trying to delete it? You should have one file per user request (That is another reason you should avoid temp files and store everything in memory).

kgiannakakis
+1  A: 

I'm assuming you have some sort of concurrency issue going on here. Consider making this method non-static, and use a unique name for your temp file (like append the current time, or use a guid for a filename). Chances are that you're opening the file, then someone else opens it, so the first delete fails.

Jesse
A: 

you can try piped input and piped output stream. those buffers need two threads one to feed the pipe (exporter) and the other (servlet) to consume data from the pipe and write it to the response output stream

Boris Pavlović