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
.ZipOutputStream
;
19 * This class offer some utilities based around Streams.
23 public class IOUtils
{
25 * Write the data to the given {@link File}.
30 * the target {@link File}
33 * in case of I/O error
35 public static void write(InputStream in
, File target
) throws IOException
{
36 OutputStream out
= new FileOutputStream(target
);
45 * Write the data to the given {@link OutputStream}.
50 * the target {@link OutputStream}
53 * in case of I/O error
55 public static void write(InputStream in
, OutputStream out
)
57 byte buffer
[] = new byte[4069];
58 for (int len
= 0; (len
= in
.read(buffer
)) > 0;) {
59 out
.write(buffer
, 0, len
);
64 * Recursively Add a {@link File} (which can thus be a directory, too) to a
65 * {@link ZipOutputStream}.
70 * the path to prepend to the ZIP info before the actual
73 * the source {@link File} (which can be a directory)
75 * FALSE if we need to add a {@link ZipEntry} for base/target,
76 * TRUE to add it at the root of the ZIP
79 * in case of I/O error
81 public static void zip(ZipOutputStream zip
, String base
, File target
,
82 boolean targetIsRoot
) throws IOException
{
83 if (target
.isDirectory()) {
85 if (base
== null || base
.isEmpty()) {
86 base
= target
.getName();
88 base
+= "/" + target
.getName();
90 zip
.putNextEntry(new ZipEntry(base
+ "/"));
92 for (File file
: target
.listFiles()) {
93 zip(zip
, base
, file
, false);
96 if (base
== null || base
.isEmpty()) {
97 base
= target
.getName();
99 base
+= "/" + target
.getName();
101 zip
.putNextEntry(new ZipEntry(base
));
102 FileInputStream in
= new FileInputStream(target
);
104 IOUtils
.write(in
, zip
);
112 * Zip the given source into dest.
115 * the source {@link File} (which can be a directory)
117 * the destination <tt>.zip</tt> file
119 * FALSE if we need to add a {@link ZipEntry} for src, TRUE to
120 * add it at the root of the ZIP
122 * @throws IOException
123 * in case of I/O error
125 public static void zip(File src
, File dest
, boolean srcIsRoot
)
127 OutputStream out
= new FileOutputStream(dest
);
129 ZipOutputStream zip
= new ZipOutputStream(out
);
131 IOUtils
.zip(zip
, "", src
, srcIsRoot
);
141 * Write the {@link String} content to {@link File}.
144 * the directory where to write the {@link File}
146 * the {@link File} name
150 * @throws IOException
151 * in case of I/O error
153 public static void writeSmallFile(File dir
, String filename
, String content
)
159 FileWriter writerVersion
= new FileWriter(new File(dir
, filename
));
161 writerVersion
.write(content
);
163 writerVersion
.close();
168 * Read the whole {@link File} content into a {@link String}.
173 * @return the content
175 * @throws IOException
176 * in case of I/O error
178 public static String
readSmallFile(File file
) throws IOException
{
179 InputStream stream
= new FileInputStream(file
);
181 return readSmallStream(stream
);
188 * Read the whole {@link InputStream} content into a {@link String}.
191 * the {@link InputStream}
193 * @return the content
195 * @throws IOException
196 * in case of I/O error
198 public static String
readSmallStream(InputStream stream
) throws IOException
{
199 // do NOT close the reader, or the related stream will be closed, too
201 BufferedReader reader
= new BufferedReader(
202 new InputStreamReader(stream
));
204 StringBuilder builder
= new StringBuilder();
205 for (String line
= reader
.readLine(); line
!= null; line
= reader
207 builder
.append(line
);
208 builder
.append("\n");
211 return builder
.toString();
215 * Recursively delete the given {@link File}, which may of course also be a
218 * Will either silently continue or throw an exception in case of error,
219 * depending upon the parameters.
222 * the target to delete
224 * TRUE to throw an {@link IOException} in case of error, FALSE
225 * to silently continue
227 * @return TRUE if all files were deleted, FALSE if an error occurred
229 * @throws IOException
230 * if an error occurred and the parameters allow an exception to
233 public static boolean deltree(File target
, boolean exception
)
235 List
<File
> list
= deltree(target
, null);
236 if (exception
&& !list
.isEmpty()) {
238 for (File file
: list
) {
239 slist
+= "\n" + file
.getPath();
242 throw new IOException("Cannot delete all the files from: <" //
243 + target
+ ">:" + slist
);
246 return list
.isEmpty();
250 * Recursively delete the given {@link File}, which may of course also be a
253 * Will silently continue in case of error.
256 * the target to delete
258 * @return TRUE if all files were deleted, FALSE if an error occurred
260 public static boolean deltree(File target
) {
261 return deltree(target
, null).isEmpty();
265 * Recursively delete the given {@link File}, which may of course also be a
268 * Will collect all {@link File} that cannot be deleted in the given
272 * the target to delete
274 * the accumulator to use for errors, or NULL to create a new one
276 * @return the errors accumulator
278 public static List
<File
> deltree(File target
, List
<File
> errorAcc
) {
279 if (errorAcc
== null) {
280 errorAcc
= new ArrayList
<File
>();
283 File
[] files
= target
.listFiles();
285 for (File file
: files
) {
286 errorAcc
= deltree(file
, errorAcc
);
290 if (!target
.delete()) {
291 errorAcc
.add(target
);
298 * Open the given /-separated resource (from the binary root).
303 * @return the opened resource if found, NLL if not
305 public static InputStream
openResource(String name
) {
306 ClassLoader loader
= IOUtils
.class.getClassLoader();
307 if (loader
== null) {
308 loader
= ClassLoader
.getSystemClassLoader();
311 return loader
.getResourceAsStream(name
);
315 * Return a resetable {@link InputStream} from this stream, and reset it.
319 * @return the resetable stream, which <b>may</b> be the same
321 * @throws IOException
322 * in case of I/O error
324 public static InputStream
forceResetableStream(InputStream in
)
326 MarkableFileInputStream tmpIn
= null;
329 boolean resetable
= in
.markSupported();
333 } catch (IOException e
) {
342 tmp
= File
.createTempFile(".tmp-stream", ".tmp");
345 tmpIn
= new MarkableFileInputStream(new FileInputStream(tmp
));
359 * Convert the {@link InputStream} into a byte array.
366 * @throws IOException
367 * in case of I/O error
369 public static byte[] toByteArray(InputStream in
) throws IOException
{
370 ByteArrayOutputStream out
= new ByteArrayOutputStream();
373 byte[] array
= out
.toByteArray();