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
18 package org.apache.any23.util;
19
20 import java.io.BufferedInputStream;
21 import java.io.BufferedOutputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.FilenameFilter;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStreamWriter;
31 import java.io.PrintWriter;
32 import java.io.Writer;
33 import java.nio.charset.StandardCharsets;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Locale;
37
38 /**
39 * Utility class for handling files.
40 *
41 * @author Michele Mostarda (mostarda@fbk.eu)
42 */
43 public class FileUtils {
44
45 /**
46 * Moves a <code>target</code> file to a new <code>dest</code> location.
47 *
48 * @param target
49 * file to be moved.
50 * @param dest
51 * dest dir.
52 *
53 * @return destination file.
54 */
55 public static File mv(File target, File dest) {
56 if (!dest.isDirectory()) {
57 throw new IllegalArgumentException("destination must be a directory.");
58 }
59
60 final File newFile = new File(dest, target.getName());
61 boolean success = target.renameTo(newFile);
62 if (!success) {
63 throw new IllegalStateException(
64 String.format(Locale.ROOT, "Cannot move target file [%s] to destination [%s]", target, newFile));
65 }
66 return newFile;
67 }
68
69 /**
70 * Copies the content of the input stream within the given dest file. The dest file must not exist.
71 *
72 * @param is
73 * {@link java.io.InputStream} to copy
74 * @param dest
75 * detination to copy it to.
76 */
77 public static void cp(InputStream is, File dest) {
78 if (dest.exists()) {
79 throw new IllegalArgumentException("Destination must not exist.");
80 }
81 BufferedInputStream bis = null;
82 BufferedOutputStream bos = null;
83 try {
84 bis = new BufferedInputStream(is);
85 FileOutputStream fos = new FileOutputStream(dest);
86 bos = new BufferedOutputStream(fos);
87 final byte[] buffer = new byte[1024 * 4];
88 int read;
89 while (true) {
90 read = bis.read(buffer);
91 if (read == -1) {
92 break;
93 }
94 bos.write(buffer, 0, read);
95 }
96 } catch (Exception e) {
97 throw new RuntimeException("Error while copying stream into file.", e);
98 } finally {
99 StreamUtils.closeGracefully(bis);
100 StreamUtils.closeGracefully(bos);
101 }
102 }
103
104 /**
105 * Copies a file <code>src</code> to the <code>dest</code>.
106 *
107 * @param src
108 * source file.
109 * @param dest
110 * destination file.
111 *
112 * @throws java.io.FileNotFoundException
113 * if file cannot be copied or created.
114 */
115 public static void cp(File src, File dest) throws FileNotFoundException {
116 FileInputStream fis = null;
117 try {
118 fis = new FileInputStream(src);
119 cp(fis, dest);
120 } finally {
121 StreamUtils.closeGracefully(fis);
122 }
123 }
124
125 /**
126 * Dumps the given string within a file.
127 *
128 * @param f
129 * file target.
130 * @param content
131 * content to be dumped.
132 *
133 * @throws IOException
134 * if there is an error dumping the content
135 */
136 public static void dumpContent(File f, String content) throws IOException {
137 Writer fw = null;
138 try {
139 fw = new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8);
140 fw.write(content);
141 } finally {
142 StreamUtils.closeGracefully(fw);
143 }
144 }
145
146 /**
147 * Dumps the stack trace of the given exception into the specified file.
148 *
149 * @param f
150 * file to generate dump.
151 * @param t
152 * exception to be dumped.
153 *
154 * @throws IOException
155 * if there is an error dumping the content
156 */
157 public static void dumpContent(File f, Throwable t) throws IOException {
158 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
159 final PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8), true);
160 t.printStackTrace(pw);
161 pw.close();
162 dumpContent(f, baos.toString("UTF-8"));
163 }
164
165 /**
166 * Reads a resource file and returns the content as a string.
167 *
168 * @param clazz
169 * the class to use load the resource.
170 * @param resource
171 * the resource to be load.
172 *
173 * @return the string representing the file content.
174 *
175 * @throws java.io.IOException
176 * if there is an error loading the resource
177 */
178 public static String readResourceContent(Class clazz, String resource) throws IOException {
179 return StreamUtils.asString(clazz.getResourceAsStream(resource));
180 }
181
182 /**
183 * Reads a resource file and returns the content as a string.
184 *
185 * @param resource
186 * the resource to be load.
187 *
188 * @return the string representing the file content.
189 *
190 * @throws java.io.IOException
191 * if there is an error loading the resource
192 */
193 public static String readResourceContent(String resource) throws IOException {
194 return readResourceContent(FileUtils.class, resource);
195 }
196
197 /**
198 * Returns the content of a file a single string.
199 *
200 * @param f
201 * the file to read.
202 *
203 * @return the content of file.
204 *
205 * @throws IOException
206 * if an error occurs while locating or accessing the file.
207 */
208 public static String readFileContent(File f) throws IOException {
209 FileInputStream fis = new FileInputStream(f);
210 return StreamUtils.asString(fis, true);
211 }
212
213 /**
214 * Returns all the lines of a file.
215 *
216 * @param f
217 * the file to read.
218 *
219 * @return a not <code>null</code> array with not <code>null</code> line strings.
220 *
221 * @throws IOException
222 * if an error occurs while locating or accessing the file.
223 */
224 public static String[] readFileLines(File f) throws IOException {
225 FileInputStream fis = new FileInputStream(f);
226 return StreamUtils.asLines(fis);
227 }
228
229 /**
230 * Lists the content of a dir applying the specified filter.
231 *
232 * @param dir
233 * directory root.
234 * @param filenameFilter
235 * filter to be applied.
236 *
237 * @return list of matching files.
238 */
239 public static File[] listFilesRecursively(File dir, FilenameFilter filenameFilter) {
240 if (!dir.isDirectory()) {
241 throw new IllegalArgumentException(dir.getAbsolutePath() + " must be a directory.");
242 }
243 final List<File> result = new ArrayList<File>();
244 visitFilesRecursively(dir, filenameFilter, result);
245 return result.toArray(new File[result.size()]);
246 }
247
248 /**
249 * Visits a directory recursively, applying the given filter and adding matches to the result list.
250 *
251 * @param dir
252 * directory to find.
253 * @param filenameFilter
254 * filter to apply.
255 * @param result
256 * result list.
257 */
258 private static void visitFilesRecursively(File dir, FilenameFilter filenameFilter, List<File> result) {
259 for (File file : dir.listFiles()) {
260 if (!file.isDirectory()) {
261 if (filenameFilter == null || filenameFilter.accept(dir, file.getName())) {
262 result.add(file);
263 }
264 } else {
265 visitFilesRecursively(file, filenameFilter, result);
266 }
267 }
268 }
269
270 /**
271 * Function class.
272 */
273 private FileUtils() {
274 }
275
276 }