Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
FileHelper |
|
| 3.857142857142857;3.857 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | package org.apache.commons.transaction.util; | |
18 | ||
19 | import java.io.File; | |
20 | import java.io.FileInputStream; | |
21 | import java.io.FileOutputStream; | |
22 | import java.io.IOException; | |
23 | import java.io.InputStream; | |
24 | import java.io.OutputStream; | |
25 | ||
26 | /** | |
27 | * Helper methods for file manipulation. | |
28 | * All methods are <em>thread safe</em>. | |
29 | * | |
30 | * @version $Id: FileHelper.java 493628 2007-01-07 01:42:48Z joerg $ | |
31 | */ | |
32 | 0 | public final class FileHelper { |
33 | ||
34 | 1 | private static int BUF_SIZE = 50000; |
35 | 1 | private static byte[] BUF = new byte[BUF_SIZE]; |
36 | ||
37 | /** | |
38 | * Deletes a file specified by a path. | |
39 | * | |
40 | * @param path path of file to be deleted | |
41 | * @return <code>true</code> if file has been deleted, <code>false</code> otherwise | |
42 | */ | |
43 | public static boolean deleteFile(String path) { | |
44 | 0 | File file = new File(path); |
45 | 0 | return file.delete(); |
46 | } | |
47 | ||
48 | /** | |
49 | * Checks if a file specified by a path exits. | |
50 | * | |
51 | * @param path path of file to be checked | |
52 | * @return <code>true</code> if file exists, <code>false</code> otherwise | |
53 | */ | |
54 | public static boolean fileExists(String path) { | |
55 | 240 | File file = new File(path); |
56 | 240 | return file.exists(); |
57 | } | |
58 | ||
59 | /** | |
60 | * Creates a file specified by a path. All necessary directories will be created. | |
61 | * | |
62 | * @param path path of file to be created | |
63 | * @return <code>true</code> if file has been created, <code>false</code> if the file already exists | |
64 | * @throws IOException | |
65 | * If an I/O error occurred | |
66 | */ | |
67 | public static boolean createFile(String path) throws IOException { | |
68 | 38 | File file = new File(path); |
69 | 38 | if (file.isDirectory()) { |
70 | 0 | return file.mkdirs(); |
71 | } else { | |
72 | 38 | File dir = file.getParentFile(); |
73 | // do not check if this worked, as it may also return false, when all neccessary dirs are present | |
74 | 38 | dir.mkdirs(); |
75 | 38 | return file.createNewFile(); |
76 | } | |
77 | } | |
78 | ||
79 | /** | |
80 | * Removes a file. If the specified file is a directory all contained files will | |
81 | * be removed recursively as well. | |
82 | * | |
83 | * @param toRemove file to be removed | |
84 | */ | |
85 | public static void removeRec(File toRemove) { | |
86 | 355 | if (toRemove.isDirectory()) { |
87 | 222 | File fileList[] = toRemove.listFiles(); |
88 | 489 | for (int a = 0; a < fileList.length; a++) { |
89 | 267 | removeRec(fileList[a]); |
90 | } | |
91 | } | |
92 | 355 | toRemove.delete(); |
93 | 355 | } |
94 | ||
95 | /** | |
96 | * Moves one directory or file to another. Existing files will be replaced. | |
97 | * | |
98 | * @param source file to move from | |
99 | * @param target file to move to | |
100 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
101 | */ | |
102 | public static void moveRec(File source, File target) throws IOException { | |
103 | 18 | byte[] sharedBuffer = new byte[BUF_SIZE]; |
104 | 18 | moveRec(source, target, sharedBuffer); |
105 | 18 | } |
106 | ||
107 | static void moveRec(File source, File target, byte[] sharedBuffer) throws IOException { | |
108 | 18 | if (source.isDirectory()) { |
109 | 18 | if (!target.exists()) { |
110 | 0 | target.mkdirs(); |
111 | } | |
112 | 18 | if (target.isDirectory()) { |
113 | ||
114 | 18 | File[] files = source.listFiles(); |
115 | 36 | for (int i = 0; i < files.length; i++) { |
116 | 18 | File file = files[i]; |
117 | 18 | File targetFile = new File(target, file.getName()); |
118 | 18 | if (file.isFile()) { |
119 | 12 | if (targetFile.exists()) { |
120 | 1 | targetFile.delete(); |
121 | } | |
122 | 12 | if (!file.renameTo(targetFile)) { |
123 | 0 | copy(file, targetFile, sharedBuffer); |
124 | 0 | file.delete(); |
125 | } | |
126 | } else { | |
127 | 6 | if (!targetFile.exists()) { |
128 | 0 | if (!targetFile.mkdirs()) { |
129 | 0 | throw new IOException("Could not create target directory: " |
130 | + targetFile); | |
131 | } | |
132 | } | |
133 | 6 | moveRec(file, targetFile); |
134 | } | |
135 | } | |
136 | 18 | source.delete(); |
137 | 18 | } |
138 | } else { | |
139 | 0 | if (!target.isDirectory()) { |
140 | 0 | copy(source, target, sharedBuffer); |
141 | 0 | source.delete(); |
142 | } | |
143 | } | |
144 | 18 | } |
145 | ||
146 | /** | |
147 | * Copies one directory or file to another. Existing files will be replaced. | |
148 | * | |
149 | * @param source directory or file to copy from | |
150 | * @param target directory or file to copy to | |
151 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
152 | */ | |
153 | public static void copyRec(File source, File target) throws IOException { | |
154 | 1 | byte[] sharedBuffer = new byte[BUF_SIZE]; |
155 | 1 | copyRec(source, target, sharedBuffer); |
156 | 1 | } |
157 | ||
158 | static void copyRec(File source, File target, byte[] sharedBuffer) throws IOException { | |
159 | 1 | if (source.isDirectory()) { |
160 | 0 | if (!target.exists()) { |
161 | 0 | target.mkdirs(); |
162 | } | |
163 | 0 | if (target.isDirectory()) { |
164 | ||
165 | 0 | File[] files = source.listFiles(); |
166 | 0 | for (int i = 0; i < files.length; i++) { |
167 | 0 | File file = files[i]; |
168 | 0 | File targetFile = new File(target, file.getName()); |
169 | 0 | if (file.isFile()) { |
170 | 0 | if (targetFile.exists()) { |
171 | 0 | targetFile.delete(); |
172 | } | |
173 | 0 | copy(file, targetFile, sharedBuffer); |
174 | } else { | |
175 | 0 | targetFile.mkdirs(); |
176 | 0 | copyRec(file, targetFile); |
177 | } | |
178 | } | |
179 | 0 | } |
180 | } else { | |
181 | 1 | if (!target.isDirectory()) { |
182 | 1 | if (!target.exists()) { |
183 | 1 | File dir = target.getParentFile(); |
184 | 1 | if(!dir.exists() && !dir.mkdirs()) { |
185 | 0 | throw new IOException("Could not create target directory: " + dir); |
186 | } | |
187 | 1 | if (!target.createNewFile()) { |
188 | 0 | throw new IOException("Could not create target file: " + target); |
189 | } | |
190 | } | |
191 | 1 | copy(source, target, sharedBuffer); |
192 | } | |
193 | } | |
194 | 1 | } |
195 | ||
196 | /** | |
197 | * Copies one file to another using {@link #copy(InputStream, OutputStream)}. | |
198 | * | |
199 | * @param input | |
200 | * source file | |
201 | * @param output | |
202 | * destination file | |
203 | * @return the number of bytes copied | |
204 | * @throws IOException | |
205 | * if an I/O error occurs (may result in partially done work) | |
206 | * @see #copy(InputStream, OutputStream) | |
207 | */ | |
208 | public static long copy(File input, File output) throws IOException { | |
209 | 0 | FileInputStream in = null; |
210 | try { | |
211 | 0 | in = new FileInputStream(input); |
212 | 0 | return copy(in, output); |
213 | } finally { | |
214 | 0 | if (in != null) { |
215 | try { | |
216 | 0 | in.close(); |
217 | 0 | } catch (IOException e) { |
218 | 0 | } |
219 | } | |
220 | } | |
221 | } | |
222 | ||
223 | /** | |
224 | * Copies one file to another using the supplied buffer. | |
225 | * | |
226 | * @param input source file | |
227 | * @param output destination file | |
228 | * @param copyBuffer buffer used for copying | |
229 | * @return the number of bytes copied | |
230 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
231 | * @see #copy(InputStream, OutputStream) | |
232 | */ | |
233 | public static long copy(File input, File output, byte[] copyBuffer) throws IOException { | |
234 | 1 | FileInputStream in = null; |
235 | 1 | FileOutputStream out = null; |
236 | try { | |
237 | 1 | in = new FileInputStream(input); |
238 | 1 | out = new FileOutputStream(output); |
239 | 1 | return copy(in, out, copyBuffer); |
240 | } finally { | |
241 | 0 | if (in != null) { |
242 | try { | |
243 | 1 | in.close(); |
244 | 0 | } catch (IOException e) { |
245 | 1 | } |
246 | } | |
247 | 1 | if (out != null) { |
248 | try { | |
249 | 1 | out.close(); |
250 | 0 | } catch (IOException e) { |
251 | 2 | } |
252 | } | |
253 | } | |
254 | } | |
255 | ||
256 | /** | |
257 | * Copies an <code>InputStream</code> to a file using {@link #copy(InputStream, OutputStream)}. | |
258 | * | |
259 | * @param in stream to copy from | |
260 | * @param outputFile file to copy to | |
261 | * @return the number of bytes copied | |
262 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
263 | * @see #copy(InputStream, OutputStream) | |
264 | */ | |
265 | public static long copy(InputStream in, File outputFile) throws IOException { | |
266 | 0 | FileOutputStream out = null; |
267 | try { | |
268 | 0 | out = new FileOutputStream(outputFile); |
269 | 0 | return copy(in, out); |
270 | } finally { | |
271 | 0 | if (out != null) { |
272 | try { | |
273 | 0 | out.close(); |
274 | 0 | } catch (IOException e) { |
275 | 0 | } |
276 | } | |
277 | } | |
278 | } | |
279 | ||
280 | /** | |
281 | * Copies an <code>InputStream</code> to an <code>OutputStream</code> using a local internal buffer for performance. | |
282 | * Compared to {@link #globalBufferCopy(InputStream, OutputStream)} this method allows for better | |
283 | * concurrency, but each time it is called generates a buffer which will be garbage. | |
284 | * | |
285 | * @param in stream to copy from | |
286 | * @param out stream to copy to | |
287 | * @return the number of bytes copied | |
288 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
289 | * @see #globalBufferCopy(InputStream, OutputStream) | |
290 | */ | |
291 | public static long copy(InputStream in, OutputStream out) throws IOException { | |
292 | // we need a buffer of our own, so no one else interferes | |
293 | 0 | byte[] buf = new byte[BUF_SIZE]; |
294 | 0 | return copy(in, out, buf); |
295 | } | |
296 | ||
297 | /** | |
298 | * Copies an <code>InputStream</code> to an <code>OutputStream</code> using a global internal buffer for performance. | |
299 | * Compared to {@link #copy(InputStream, OutputStream)} this method generated no garbage, | |
300 | * but decreases concurrency. | |
301 | * | |
302 | * @param in stream to copy from | |
303 | * @param out stream to copy to | |
304 | * @return the number of bytes copied | |
305 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
306 | * @see #copy(InputStream, OutputStream) | |
307 | */ | |
308 | public static long globalBufferCopy(InputStream in, OutputStream out) throws IOException { | |
309 | 0 | synchronized (BUF) { |
310 | 0 | return copy(in, out, BUF); |
311 | 0 | } |
312 | } | |
313 | ||
314 | /** | |
315 | * Copies an <code>InputStream</code> to an <code>OutputStream</code> using the specified buffer. | |
316 | * | |
317 | * @param in stream to copy from | |
318 | * @param out stream to copy to | |
319 | * @param copyBuffer buffer used for copying | |
320 | * @return the number of bytes copied | |
321 | * @throws IOException if an I/O error occurs (may result in partially done work) | |
322 | * @see #globalBufferCopy(InputStream, OutputStream) | |
323 | * @see #copy(InputStream, OutputStream) | |
324 | */ | |
325 | public static long copy(InputStream in, OutputStream out, byte[] copyBuffer) throws IOException { | |
326 | 1 | long bytesCopied = 0; |
327 | 1 | int read = -1; |
328 | ||
329 | 1 | while ((read = in.read(copyBuffer, 0, copyBuffer.length)) != -1) { |
330 | 0 | out.write(copyBuffer, 0, read); |
331 | 0 | bytesCopied += read; |
332 | } | |
333 | 1 | return bytesCopied; |
334 | } | |
335 | } |