traces, select TMP
[fanfix.git] / src / be / nikiroo / utils / TempFiles.java
CommitLineData
59864f77
NR
1package be.nikiroo.utils;
2
3import java.io.Closeable;
4import java.io.File;
5import java.io.IOException;
6
7/**
8 * A small utility class to generate auto-delete temporary files in a
9 * centralised location.
10 *
11 * @author niki
12 */
13public class TempFiles implements Closeable {
82fcfcde
NR
14 /**
15 * Root directory of this instance, owned by it, where all temporary files
16 * must reside.
17 */
59864f77
NR
18 protected File root;
19
20 /**
21 * Create a new {@link TempFiles} -- each instance is separate and have a
22 * dedicated sub-directory in a shared temporary root.
23 * <p>
24 * The whole repository will be deleted on close (if you fail to call it,
82fcfcde 25 * the program will <b>try</b> to call it on JVM termination).
59864f77
NR
26 *
27 * @param name
28 * the instance name (will be <b>part</b> of the final directory
29 * name)
30 *
31 * @throws IOException
32 * in case of I/O error
33 */
34 public TempFiles(String name) throws IOException {
82fcfcde
NR
35 this(null, name);
36 }
37
38 /**
39 * Create a new {@link TempFiles} -- each instance is separate and have a
40 * dedicated sub-directory in a given temporary root.
41 * <p>
42 * The whole repository will be deleted on close (if you fail to call it,
43 * the program will <b>try</b> to call it on JVM termination).
44 * <p>
45 * Be careful, this instance will <b>own</b> the given root directory, and
46 * will most probably delete all its files.
47 *
48 * @param base
49 * the root base directory to use for all the temporary files of
50 * this instance (if NULL, will be the default temporary
51 * directory of the OS)
52 * @param name
53 * the instance name (will be <b>part</b> of the final directory
54 * name)
55 *
56 * @throws IOException
57 * in case of I/O error
58 */
59 public TempFiles(File base, String name) throws IOException {
60 if (base == null) {
61 base = File.createTempFile(".temp", "");
62 }
63
64 root = base;
65
59864f77
NR
66 IOUtils.deltree(root, true);
67
68 root = new File(root.getParentFile(), ".temp");
69 root.mkdir();
70 if (!root.exists()) {
71 throw new IOException("Cannot create root directory: " + root);
72 }
73
74 root.deleteOnExit();
75
76 root = createTempFile(name);
77 IOUtils.deltree(root, true);
78
79 root.mkdir();
80 if (!root.exists()) {
81 throw new IOException("Cannot create root subdirectory: " + root);
82 }
83 }
84
85 /**
86 * Create an auto-delete temporary file.
87 *
88 * @param name
89 * a base for the final filename (only a <b>part</b> of said
90 * filename)
91 *
92 * @return the newly created file
93 *
94 * @throws IOException
95 * in case of I/O errors
96 */
97 public synchronized File createTempFile(String name) throws IOException {
98 name += "_";
99 while (name.length() < 3) {
100 name += "_";
101 }
102
103 while (true) {
104 File tmp = File.createTempFile(name, "");
105 IOUtils.deltree(tmp, true);
106
107 File test = new File(root, tmp.getName());
108 if (!test.exists()) {
109 test.createNewFile();
110 if (!test.exists()) {
111 throw new IOException("Cannot create temporary file: "
112 + test);
113 }
114
115 test.deleteOnExit();
116 return test;
117 }
118 }
119 }
120
121 /**
122 * Create an auto-delete temporary directory.
123 * <p>
124 * Note that creating 2 temporary directories with the same name will result
125 * in two <b>different</b> directories, even if the final name is the same
126 * (the absolute path will be different).
127 *
128 * @param name
129 * the actual directory name (not path)
130 *
131 * @return the newly created file
132 *
133 * @throws IOException
134 * in case of I/O errors, or if the name was a path instead of a
135 * name
136 */
137 public synchronized File createTempDir(String name) throws IOException {
138 File localRoot = createTempFile(name);
139 IOUtils.deltree(localRoot, true);
140
141 localRoot.mkdir();
142 if (!localRoot.exists()) {
143 throw new IOException("Cannot create subdirectory: " + localRoot);
144 }
145
146 File dir = new File(localRoot, name);
147 if (!dir.getName().equals(name)) {
148 throw new IOException(
149 "Cannot create temporary directory with a path, only names are allowed: "
150 + dir);
151 }
152
153 dir.mkdir();
154 dir.deleteOnExit();
155
156 if (!dir.exists()) {
157 throw new IOException("Cannot create subdirectory: " + dir);
158 }
159
160 return dir;
161 }
162
163 @Override
164 public synchronized void close() throws IOException {
165 IOUtils.deltree(root); // NO exception here
166 root.getParentFile().delete(); // only if empty
c175bf6f 167 root = null;
59864f77
NR
168 }
169
170 @Override
171 protected void finalize() throws Throwable {
172 try {
173 close();
174 } finally {
175 super.finalize();
176 }
177 }
178}