1   package com.atlassian.core.spool;
2   
3   import org.apache.log4j.Category;
4   
5   import java.io.*;
6   
7   /**
8    * A FileInputStream that deletes its input file when closed. Useful for transient file spooling.
9    *
10   * Because we don't know when a database will have finished using the stream, or if it will close it itself, this class
11   * closes the stream when all the data has been read from it.
12   */
13  public class SpoolFileInputStream extends FileInputStream {
14  
15      private static final Category log = Category.getInstance(SpoolFileInputStream.class);
16  
17      private File fileToDelete;
18  
19      private boolean closed = false;
20  
21      /**
22       * @param file
23       * @throws FileNotFoundException
24       */
25      public SpoolFileInputStream(File file) throws FileNotFoundException
26      {
27          super(file);
28          init(file);
29      }
30  
31      /**
32       * @param name
33       * @throws FileNotFoundException
34       */
35      public SpoolFileInputStream(String name) throws FileNotFoundException
36      {
37          super(name);
38          init(new File(name));
39      }
40  
41      private void init(File file)
42      {
43          this.fileToDelete = file;
44      }
45  
46      /* (non-Javadoc)
47            * @see java.io.FileInputStream#close()
48            */
49      public void close() throws IOException
50      {
51          try {
52              closed = true;
53              super.close();
54          }
55          catch (IOException ex)
56          {
57              log.error("Error closing spool stream", ex);
58          }
59          finally
60          {
61              if (fileToDelete.exists() && !fileToDelete.delete())
62              {
63                  log.warn("Could not delete spool file " + fileToDelete);
64              }
65          }
66      }
67  
68      public int read() throws IOException
69      {
70          if (closed)
71          {
72              return -1;
73          }
74          int n = super.read();
75          if (n == -1)
76          {
77              close();
78          }
79          return n;
80      }
81  
82      public int read(byte b[]) throws IOException
83      {
84          if (closed)
85          {
86              return -1;
87          }
88          int n = super.read(b);
89          if (n == -1)
90          {
91              close();
92          }
93          return n;    }
94  
95      public int read(byte b[], int off, int len) throws IOException
96      {
97          if (closed)
98          {
99              return -1;
100         }
101         int n = super.read(b, off, len);
102         if (n == -1)
103         {
104             close();
105         }
106         return n;
107     }
108 }