1 package be
.nikiroo
.utils
;
3 import java
.io
.BufferedReader
;
4 import java
.io
.ByteArrayOutputStream
;
6 import java
.io
.FileInputStream
;
7 import java
.io
.FileOutputStream
;
8 import java
.io
.FileWriter
;
9 import java
.io
.IOException
;
10 import java
.io
.InputStream
;
11 import java
.io
.InputStreamReader
;
12 import java
.io
.OutputStream
;
13 import java
.util
.ArrayList
;
14 import java
.util
.List
;
15 import java
.util
.zip
.ZipEntry
;
16 import java
.util
.zip
.ZipInputStream
;
17 import java
.util
.zip
.ZipOutputStream
;
20 * This class offer some utilities based around Streams.
24 public class IOUtils
{
26 * Write the data to the given {@link File}.
31 * the target {@link File}
34 * in case of I/O error
36 public static void write(InputStream in
, File target
) throws IOException
{
37 OutputStream out
= new FileOutputStream(target
);
46 * Write the data to the given {@link OutputStream}.
51 * the target {@link OutputStream}
54 * in case of I/O error
56 public static void write(InputStream in
, OutputStream out
)
58 byte buffer
[] = new byte[4069];
59 for (int len
= 0; (len
= in
.read(buffer
)) > 0;) {
60 out
.write(buffer
, 0, len
);
65 * Recursively Add a {@link File} (which can thus be a directory, too) to a
66 * {@link ZipOutputStream}.
71 * the path to prepend to the ZIP info before the actual
74 * the source {@link File} (which can be a directory)
76 * FALSE if we need to add a {@link ZipEntry} for base/target,
77 * TRUE to add it at the root of the ZIP
80 * in case of I/O error
82 public static void zip(ZipOutputStream zip
, String base
, File target
,
83 boolean targetIsRoot
) throws IOException
{
84 if (target
.isDirectory()) {
86 if (base
== null || base
.isEmpty()) {
87 base
= target
.getName();
89 base
+= "/" + target
.getName();
91 zip
.putNextEntry(new ZipEntry(base
+ "/"));
94 File
[] files
= target
.listFiles();
96 for (File file
: files
) {
97 zip(zip
, base
, file
, false);
101 if (base
== null || base
.isEmpty()) {
102 base
= target
.getName();
104 base
+= "/" + target
.getName();
106 zip
.putNextEntry(new ZipEntry(base
));
107 FileInputStream in
= new FileInputStream(target
);
109 IOUtils
.write(in
, zip
);
117 * Zip the given source into dest.
120 * the source {@link File} (which can be a directory)
122 * the destination <tt>.zip</tt> file
124 * FALSE if we need to add a {@link ZipEntry} for src, TRUE to
125 * add it at the root of the ZIP
127 * @throws IOException
128 * in case of I/O error
130 public static void zip(File src
, File dest
, boolean srcIsRoot
)
132 OutputStream out
= new FileOutputStream(dest
);
134 ZipOutputStream zip
= new ZipOutputStream(out
);
136 IOUtils
.zip(zip
, "", src
, srcIsRoot
);
146 * Unzip the given ZIP file into the target directory.
150 * @param targetDirectory
151 * the target directory
153 * @return the number of extracted files (not directories)
155 * @throws IOException
156 * in case of I/O errors
158 public static long unzip(File zipFile
, File targetDirectory
)
162 if (targetDirectory
.exists() && targetDirectory
.isFile()) {
163 throw new IOException("Cannot unzip " + zipFile
+ " into "
164 + targetDirectory
+ ": it is not a directory");
167 targetDirectory
.mkdir();
168 if (!targetDirectory
.exists()) {
169 throw new IOException("Cannot create target directory "
173 FileInputStream in
= new FileInputStream(zipFile
);
175 ZipInputStream zipStream
= new ZipInputStream(in
);
177 for (ZipEntry entry
= zipStream
.getNextEntry(); entry
!= null; entry
= zipStream
179 File file
= new File(targetDirectory
, entry
.getName());
180 if (entry
.isDirectory()) {
183 IOUtils
.write(zipStream
, file
);
198 * Write the {@link String} content to {@link File}.
201 * the directory where to write the {@link File}
203 * the {@link File} name
207 * @throws IOException
208 * in case of I/O error
210 public static void writeSmallFile(File dir
, String filename
, String content
)
216 writeSmallFile(new File(dir
, filename
), content
);
220 * Write the {@link String} content to {@link File}.
223 * the {@link File} to write
227 * @throws IOException
228 * in case of I/O error
230 public static void writeSmallFile(File file
, String content
)
232 FileWriter writerVersion
= new FileWriter(file
);
234 writerVersion
.write(content
);
236 writerVersion
.close();
241 * Read the whole {@link File} content into a {@link String}.
246 * @return the content
248 * @throws IOException
249 * in case of I/O error
251 public static String
readSmallFile(File file
) throws IOException
{
252 InputStream stream
= new FileInputStream(file
);
254 return readSmallStream(stream
);
261 * Read the whole {@link InputStream} content into a {@link String}.
264 * the {@link InputStream}
266 * @return the content
268 * @throws IOException
269 * in case of I/O error
271 public static String
readSmallStream(InputStream stream
) throws IOException
{
272 // do NOT close the reader, or the related stream will be closed, too
274 BufferedReader reader
= new BufferedReader(
275 new InputStreamReader(stream
));
277 StringBuilder builder
= new StringBuilder();
278 for (String line
= reader
.readLine(); line
!= null; line
= reader
280 builder
.append(line
);
281 builder
.append("\n");
284 return builder
.toString();
288 * Recursively delete the given {@link File}, which may of course also be a
291 * Will either silently continue or throw an exception in case of error,
292 * depending upon the parameters.
295 * the target to delete
297 * TRUE to throw an {@link IOException} in case of error, FALSE
298 * to silently continue
300 * @return TRUE if all files were deleted, FALSE if an error occurred
302 * @throws IOException
303 * if an error occurred and the parameters allow an exception to
306 public static boolean deltree(File target
, boolean exception
)
308 List
<File
> list
= deltree(target
, null);
309 if (exception
&& !list
.isEmpty()) {
310 StringBuilder slist
= new StringBuilder();
311 for (File file
: list
) {
312 slist
.append("\n").append(file
.getPath());
315 throw new IOException("Cannot delete all the files from: <" //
316 + target
+ ">:" + slist
.toString());
319 return list
.isEmpty();
323 * Recursively delete the given {@link File}, which may of course also be a
326 * Will silently continue in case of error.
329 * the target to delete
331 * @return TRUE if all files were deleted, FALSE if an error occurred
333 public static boolean deltree(File target
) {
334 return deltree(target
, null).isEmpty();
338 * Recursively delete the given {@link File}, which may of course also be a
341 * Will collect all {@link File} that cannot be deleted in the given
345 * the target to delete
347 * the accumulator to use for errors, or NULL to create a new one
349 * @return the errors accumulator
351 public static List
<File
> deltree(File target
, List
<File
> errorAcc
) {
352 if (errorAcc
== null) {
353 errorAcc
= new ArrayList
<File
>();
356 File
[] files
= target
.listFiles();
358 for (File file
: files
) {
359 errorAcc
= deltree(file
, errorAcc
);
363 if (!target
.delete()) {
364 errorAcc
.add(target
);
371 * Open the given /-separated resource (from the binary root).
376 * @return the opened resource if found, NLL if not
378 public static InputStream
openResource(String name
) {
379 ClassLoader loader
= IOUtils
.class.getClassLoader();
380 if (loader
== null) {
381 loader
= ClassLoader
.getSystemClassLoader();
384 return loader
.getResourceAsStream(name
);
388 * Return a resetable {@link InputStream} from this stream, and reset it.
392 * @return the resetable stream, which <b>may</b> be the same
394 * @throws IOException
395 * in case of I/O error
397 public static InputStream
forceResetableStream(InputStream in
)
399 MarkableFileInputStream tmpIn
= null;
402 boolean resetable
= in
.markSupported();
406 } catch (IOException e
) {
415 tmp
= File
.createTempFile(".tmp-stream", ".tmp");
418 tmpIn
= new MarkableFileInputStream(new FileInputStream(tmp
));
432 * Convert the {@link InputStream} into a byte array.
439 * @throws IOException
440 * in case of I/O error
442 public static byte[] toByteArray(InputStream in
) throws IOException
{
443 ByteArrayOutputStream out
= new ByteArrayOutputStream();
446 byte[] array
= out
.toByteArray();