Commit | Line | Data |
---|---|---|
59864f77 NR |
1 | package be.nikiroo.utils; |
2 | ||
3 | import java.io.Closeable; | |
4 | import java.io.File; | |
5 | import 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 | */ | |
13 | public class TempFiles implements Closeable { | |
14 | protected File root; | |
15 | ||
16 | /** | |
17 | * Create a new {@link TempFiles} -- each instance is separate and have a | |
18 | * dedicated sub-directory in a shared temporary root. | |
19 | * <p> | |
20 | * The whole repository will be deleted on close (if you fail to call it, | |
21 | * the program will <b>try</b> to all it on JVM termination). | |
22 | * | |
23 | * @param name | |
24 | * the instance name (will be <b>part</b> of the final directory | |
25 | * name) | |
26 | * | |
27 | * @throws IOException | |
28 | * in case of I/O error | |
29 | */ | |
30 | public TempFiles(String name) throws IOException { | |
31 | root = File.createTempFile(".temp", ""); | |
32 | IOUtils.deltree(root, true); | |
33 | ||
34 | root = new File(root.getParentFile(), ".temp"); | |
35 | root.mkdir(); | |
36 | if (!root.exists()) { | |
37 | throw new IOException("Cannot create root directory: " + root); | |
38 | } | |
39 | ||
40 | root.deleteOnExit(); | |
41 | ||
42 | root = createTempFile(name); | |
43 | IOUtils.deltree(root, true); | |
44 | ||
45 | root.mkdir(); | |
46 | if (!root.exists()) { | |
47 | throw new IOException("Cannot create root subdirectory: " + root); | |
48 | } | |
49 | } | |
50 | ||
51 | /** | |
52 | * Create an auto-delete temporary file. | |
53 | * | |
54 | * @param name | |
55 | * a base for the final filename (only a <b>part</b> of said | |
56 | * filename) | |
57 | * | |
58 | * @return the newly created file | |
59 | * | |
60 | * @throws IOException | |
61 | * in case of I/O errors | |
62 | */ | |
63 | public synchronized File createTempFile(String name) throws IOException { | |
64 | name += "_"; | |
65 | while (name.length() < 3) { | |
66 | name += "_"; | |
67 | } | |
68 | ||
69 | while (true) { | |
70 | File tmp = File.createTempFile(name, ""); | |
71 | IOUtils.deltree(tmp, true); | |
72 | ||
73 | File test = new File(root, tmp.getName()); | |
74 | if (!test.exists()) { | |
75 | test.createNewFile(); | |
76 | if (!test.exists()) { | |
77 | throw new IOException("Cannot create temporary file: " | |
78 | + test); | |
79 | } | |
80 | ||
81 | test.deleteOnExit(); | |
82 | return test; | |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | /** | |
88 | * Create an auto-delete temporary directory. | |
89 | * <p> | |
90 | * Note that creating 2 temporary directories with the same name will result | |
91 | * in two <b>different</b> directories, even if the final name is the same | |
92 | * (the absolute path will be different). | |
93 | * | |
94 | * @param name | |
95 | * the actual directory name (not path) | |
96 | * | |
97 | * @return the newly created file | |
98 | * | |
99 | * @throws IOException | |
100 | * in case of I/O errors, or if the name was a path instead of a | |
101 | * name | |
102 | */ | |
103 | public synchronized File createTempDir(String name) throws IOException { | |
104 | File localRoot = createTempFile(name); | |
105 | IOUtils.deltree(localRoot, true); | |
106 | ||
107 | localRoot.mkdir(); | |
108 | if (!localRoot.exists()) { | |
109 | throw new IOException("Cannot create subdirectory: " + localRoot); | |
110 | } | |
111 | ||
112 | File dir = new File(localRoot, name); | |
113 | if (!dir.getName().equals(name)) { | |
114 | throw new IOException( | |
115 | "Cannot create temporary directory with a path, only names are allowed: " | |
116 | + dir); | |
117 | } | |
118 | ||
119 | dir.mkdir(); | |
120 | dir.deleteOnExit(); | |
121 | ||
122 | if (!dir.exists()) { | |
123 | throw new IOException("Cannot create subdirectory: " + dir); | |
124 | } | |
125 | ||
126 | return dir; | |
127 | } | |
128 | ||
129 | @Override | |
130 | public synchronized void close() throws IOException { | |
131 | IOUtils.deltree(root); // NO exception here | |
132 | root.getParentFile().delete(); // only if empty | |
c175bf6f | 133 | root = null; |
59864f77 NR |
134 | } |
135 | ||
136 | @Override | |
137 | protected void finalize() throws Throwable { | |
138 | try { | |
139 | close(); | |
140 | } finally { | |
141 | super.finalize(); | |
142 | } | |
143 | } | |
144 | } |