|
21 | 21 | import static java.io.File.createTempFile;
|
22 | 22 |
|
23 | 23 | import java.io.File;
|
24 |
| -import java.io.FileFilter; |
25 |
| -import java.io.FileInputStream; |
26 |
| -import java.io.FileNotFoundException; |
27 |
| -import java.io.FileOutputStream; |
28 |
| -import java.io.IOException; |
29 |
| -import java.io.PrintWriter; |
30 |
| -import java.nio.file.Files; |
31 |
| -import java.util.Collections; |
32 |
| -import java.util.HashMap; |
33 |
| -import java.util.HashSet; |
34 |
| -import java.util.Map; |
35 |
| -import java.util.Scanner; |
36 |
| -import java.util.Set; |
37 | 24 |
|
38 | 25 | public class FileTools {
|
39 |
| - private static final int WINDOWS_RETRY_COUNT = 5; |
40 |
| - |
41 |
| - public static void deleteRecursively(File file) { |
42 |
| - if (file.isDirectory()) { |
43 |
| - var files = file.listFiles(); |
44 |
| - if (files != null) { |
45 |
| - for (var sub : files) { |
46 |
| - deleteRecursively(sub); |
47 |
| - } |
48 |
| - } |
49 |
| - } |
50 |
| - |
51 |
| - //noinspection ResultOfMethodCallIgnored |
52 |
| - file.delete(); |
53 |
| - } |
54 |
| - |
55 | 26 | public static File tempFile(String prefix, String suffix) throws Throwable {
|
56 | 27 | var file = createTempFile(prefix, suffix);
|
57 | 28 | file.deleteOnExit();
|
58 | 29 | return file;
|
59 | 30 | }
|
60 |
| - |
61 |
| - public static File tempFile(String prefix) throws Throwable { |
62 |
| - return tempFile(prefix, ".tmp"); |
63 |
| - } |
64 |
| - |
65 |
| - public static boolean deleteFile(File file) { |
66 |
| - if (!file.exists()) { |
67 |
| - return true; |
68 |
| - } |
69 |
| - var count = 0; |
70 |
| - boolean deleted; |
71 |
| - do { |
72 |
| - deleted = file.delete(); |
73 |
| - if (!deleted) { |
74 |
| - count++; |
75 |
| - waitAndThenTriggerGC(); |
76 |
| - } |
77 |
| - } while (!deleted && count <= WINDOWS_RETRY_COUNT); |
78 |
| - return deleted; |
79 |
| - } |
80 |
| - |
81 |
| - public static void moveFile(File toMove, File target) throws IOException { |
82 |
| - if (!toMove.exists()) { |
83 |
| - throw new FileNotFoundException("Source file[" + toMove.getAbsolutePath() + "] not found"); |
84 |
| - } |
85 |
| - if (target.exists()) { |
86 |
| - throw new IOException("Target file[" + target.getAbsolutePath() + "] already exists"); |
87 |
| - } |
88 |
| - |
89 |
| - if (toMove.renameTo(target)) { |
90 |
| - return; |
91 |
| - } |
92 |
| - |
93 |
| - if (toMove.isDirectory()) { |
94 |
| - Files.createDirectories(target.toPath()); |
95 |
| - copyRecursively(toMove, target, null); |
96 |
| - deleteRecursively(toMove); |
97 |
| - } else { |
98 |
| - copyFile(toMove, target); |
99 |
| - deleteFile(toMove); |
100 |
| - } |
101 |
| - } |
102 |
| - |
103 |
| - public static void copyRecursively(File fromDirectory, File toDirectory, FileFilter filter) throws IOException { |
104 |
| - for (var fromFile : fromDirectory.listFiles(filter)) { |
105 |
| - var toFile = new File(toDirectory, fromFile.getName()); |
106 |
| - if (fromFile.isDirectory()) { |
107 |
| - Files.createDirectories(toFile.toPath()); |
108 |
| - copyRecursively(fromFile, toFile, filter); |
109 |
| - } else { |
110 |
| - copyFile(fromFile, toFile); |
111 |
| - } |
112 |
| - } |
113 |
| - } |
114 |
| - |
115 |
| - public static void copyFile(File srcFile, File dstFile) throws IOException { |
116 |
| - var parentFile = dstFile.getParentFile(); |
117 |
| - if (parentFile != null) { |
118 |
| - //noinspection ResultOfMethodCallIgnored |
119 |
| - parentFile.mkdirs(); |
120 |
| - } |
121 |
| - try (var input = new FileInputStream(srcFile); |
122 |
| - var output = new FileOutputStream(dstFile)) { |
123 |
| - var bufferSize = 1024; |
124 |
| - var buffer = new byte[bufferSize]; |
125 |
| - int bytesRead; |
126 |
| - while ((bytesRead = input.read(buffer)) != -1) { |
127 |
| - output.write(buffer, 0, bytesRead); |
128 |
| - } |
129 |
| - } catch (IOException e) { |
130 |
| - // Because the message from this cause may not mention which file it's about |
131 |
| - throw new IOException( |
132 |
| - "Could not copy '" + srcFile.getCanonicalPath() + "' to '" + dstFile.getCanonicalPath() + "'", e); |
133 |
| - } |
134 |
| - } |
135 |
| - |
136 |
| - /* |
137 |
| - * See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4715154. |
138 |
| - */ |
139 |
| - @SuppressWarnings("ResultOfMethodCallIgnored") |
140 |
| - private static void waitAndThenTriggerGC() { |
141 |
| - try { |
142 |
| - Thread.sleep(500); |
143 |
| - } catch (InterruptedException ee) { |
144 |
| - Thread.interrupted(); |
145 |
| - } // ok |
146 |
| - System.gc(); |
147 |
| - } |
148 |
| - |
149 |
| - public static void updateProperty(File propFile, String key, String value) throws IOException { |
150 |
| - Map<String, String> propertiesMap = new HashMap<>(1); |
151 |
| - propertiesMap.put(key, value); |
152 |
| - updateProperties(propFile, propertiesMap, Collections.emptySet()); |
153 |
| - } |
154 |
| - |
155 |
| - public static void updateProperties(File propFile, Map<String, String> propertiesMap, Set<String> excludes) |
156 |
| - throws IOException { |
157 |
| - var in = new Scanner(propFile); |
158 |
| - |
159 |
| - Set<String> updatedProperties = new HashSet<>(propertiesMap.size()); |
160 |
| - var newPropFile = File.createTempFile(propFile.getName(), null); |
161 |
| - |
162 |
| - try { |
163 |
| - var outStream = new FileOutputStream(newPropFile); |
164 |
| - var out = new PrintWriter(outStream); |
165 |
| - |
166 |
| - while (in.hasNextLine()) { |
167 |
| - var line = in.nextLine(); |
168 |
| - if (!line.trim().startsWith("#")) { |
169 |
| - var tokens = line.split("="); |
170 |
| - if (tokens.length == 2) { |
171 |
| - var name = tokens[0].trim(); |
172 |
| - if (excludes.contains(name)) { |
173 |
| - continue; |
174 |
| - } |
175 |
| - |
176 |
| - Object value = propertiesMap.get(name); |
177 |
| - if (value != null && !updatedProperties.contains(name)) { |
178 |
| - // found property and set it to the new value |
179 |
| - printlnProperty(out, name, value); |
180 |
| - updatedProperties.add(name); |
181 |
| - } else { |
182 |
| - // not the property that we are looking for, print it as original |
183 |
| - out.println(line); |
184 |
| - } |
185 |
| - } else { |
186 |
| - // not the property that we are looking for, print it as original |
187 |
| - out.println(line); |
188 |
| - } |
189 |
| - } else { |
190 |
| - // comments, print as original |
191 |
| - out.println(line); |
192 |
| - } |
193 |
| - } |
194 |
| - |
195 |
| - for (var entry : propertiesMap.entrySet()) { |
196 |
| - var name = entry.getKey(); |
197 |
| - Object value = entry.getValue(); |
198 |
| - if (value != null && !updatedProperties.contains(name)) { |
199 |
| - // add this as a new prop |
200 |
| - printlnProperty(out, name, value); |
201 |
| - } |
202 |
| - } |
203 |
| - |
204 |
| - in.close(); |
205 |
| - out.flush(); |
206 |
| - out.close(); |
207 |
| - deleteFile(propFile); |
208 |
| - moveFile(newPropFile, propFile); |
209 |
| - } catch (IOException | RuntimeException e) { |
210 |
| - newPropFile.deleteOnExit(); |
211 |
| - throw e; |
212 |
| - } |
213 |
| - } |
214 |
| - |
215 |
| - private static void printlnProperty(PrintWriter out, String name, Object value) { |
216 |
| - out.print(name); |
217 |
| - out.print('='); |
218 |
| - out.println(value); |
219 |
| - } |
220 | 31 | }
|
0 commit comments