X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2FIOUtils.java;h=9ab638af06e1486122de1c059abec3eb5b0a4980;hb=12784931c8ae440fec10dfd6ea97e7b16ba64988;hp=eb105e2698535e325ed602fc0b3ed50f7e0b16b4;hpb=32ae20790403c7bce40bf278db8ca0258623945c;p=fanfix.git diff --git a/src/be/nikiroo/utils/IOUtils.java b/src/be/nikiroo/utils/IOUtils.java index eb105e2..9ab638a 100644 --- a/src/be/nikiroo/utils/IOUtils.java +++ b/src/be/nikiroo/utils/IOUtils.java @@ -1,25 +1,22 @@ package be.nikiroo.utils; -import java.awt.Image; -import java.awt.geom.AffineTransform; -import java.awt.image.AffineTransformOp; -import java.awt.image.BufferedImage; -import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; -import javax.imageio.ImageIO; +import be.nikiroo.utils.streams.MarkableFileInputStream; /** - * This class offer some utilities based around Streams. + * This class offer some utilities based around Streams and Files. * * @author niki */ @@ -49,7 +46,7 @@ public class IOUtils { * * @param in * the data source - * @param target + * @param out * the target {@link OutputStream} * * @throws IOException @@ -57,9 +54,11 @@ public class IOUtils { */ public static void write(InputStream in, OutputStream out) throws IOException { - byte buffer[] = new byte[4069]; - for (int len = 0; (len = in.read(buffer)) > 0;) { + byte buffer[] = new byte[4096]; + int len = in.read(buffer); + while (len > -1) { out.write(buffer, 0, len); + len = in.read(buffer); } } @@ -92,8 +91,12 @@ public class IOUtils { } zip.putNextEntry(new ZipEntry(base + "/")); } - for (File file : target.listFiles()) { - zip(zip, base, file, false); + + File[] files = target.listFiles(); + if (files != null) { + for (File file : files) { + zip(zip, base, file, false); + } } } else { if (base == null || base.isEmpty()) { @@ -118,7 +121,7 @@ public class IOUtils { * the source {@link File} (which can be a directory) * @param dest * the destination .zip file - * @param srctIsRoot + * @param srcIsRoot * FALSE if we need to add a {@link ZipEntry} for src, TRUE to * add it at the root of the ZIP * @@ -140,6 +143,58 @@ public class IOUtils { } } + /** + * Unzip the given ZIP file into the target directory. + * + * @param zipFile + * the ZIP file + * @param targetDirectory + * the target directory + * + * @return the number of extracted files (not directories) + * + * @throws IOException + * in case of I/O errors + */ + public static long unzip(File zipFile, File targetDirectory) + throws IOException { + long count = 0; + + if (targetDirectory.exists() && targetDirectory.isFile()) { + throw new IOException("Cannot unzip " + zipFile + " into " + + targetDirectory + ": it is not a directory"); + } + + targetDirectory.mkdir(); + if (!targetDirectory.exists()) { + throw new IOException("Cannot create target directory " + + targetDirectory); + } + + FileInputStream in = new FileInputStream(zipFile); + try { + ZipInputStream zipStream = new ZipInputStream(in); + try { + for (ZipEntry entry = zipStream.getNextEntry(); entry != null; entry = zipStream + .getNextEntry()) { + File file = new File(targetDirectory, entry.getName()); + if (entry.isDirectory()) { + file.mkdirs(); + } else { + IOUtils.write(zipStream, file); + count++; + } + } + } finally { + zipStream.close(); + } + } finally { + in.close(); + } + + return count; + } + /** * Write the {@link String} content to {@link File}. * @@ -159,11 +214,27 @@ public class IOUtils { dir.mkdirs(); } - FileWriter writerVersion = new FileWriter(new File(dir, filename)); + writeSmallFile(new File(dir, filename), content); + } + + /** + * Write the {@link String} content to {@link File}. + * + * @param file + * the {@link File} to write + * @param content + * the content + * + * @throws IOException + * in case of I/O error + */ + public static void writeSmallFile(File file, String content) + throws IOException { + FileOutputStream out = new FileOutputStream(file); try { - writerVersion.write(content); + out.write(content.getBytes("UTF-8")); } finally { - writerVersion.close(); + out.close(); } } @@ -179,16 +250,33 @@ public class IOUtils { * in case of I/O error */ public static String readSmallFile(File file) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(file)); + InputStream stream = new FileInputStream(file); try { - StringBuilder builder = new StringBuilder(); - for (String line = reader.readLine(); line != null; line = reader - .readLine()) { - builder.append(line); - } - return builder.toString(); + return readSmallStream(stream); + } finally { + stream.close(); + } + } + + /** + * Read the whole {@link InputStream} content into a {@link String}. + * + * @param stream + * the {@link InputStream} + * + * @return the content + * + * @throws IOException + * in case of I/O error + */ + public static String readSmallStream(InputStream stream) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + write(stream, out); + return out.toString("UTF-8"); } finally { - reader.close(); + // do NOT close, or the related stream will be closed, too + // out.close(); } } @@ -196,137 +284,83 @@ public class IOUtils { * Recursively delete the given {@link File}, which may of course also be a * directory. *
- * Will silently continue in case of error.
+ * Will either silently continue or throw an exception in case of error,
+ * depending upon the parameters.
*
* @param target
* the target to delete
+ * @param exception
+ * TRUE to throw an {@link IOException} in case of error, FALSE
+ * to silently continue
+ *
+ * @return TRUE if all files were deleted, FALSE if an error occurred
+ *
+ * @throws IOException
+ * if an error occurred and the parameters allow an exception to
+ * be thrown
*/
- public static void deltree(File target) {
- for (File file : target.listFiles()) {
- if (file.isDirectory()) {
- deltree(file);
- } else {
- if (!file.delete()) {
- System.err.println("Cannot delete file: "
- + file.getAbsolutePath());
- }
+ public static boolean deltree(File target, boolean exception)
+ throws IOException {
+ List
+ * Will silently continue in case of error.
*
- * @return the {@link Image} object
+ * @param target
+ * the target to delete
*
- * @throws IOException
- * in case of IO error
+ * @return TRUE if all files were deleted, FALSE if an error occurred
*/
- public static BufferedImage toImage(InputStream in) throws IOException {
- MarkableFileInputStream tmpIn = null;
- File tmp = null;
- try {
- in.reset();
- } catch (IOException e) {
- tmp = File.createTempFile("fanfic-tmp-image", ".tmp");
- tmp.deleteOnExit();
- IOUtils.write(in, tmp);
- tmpIn = new MarkableFileInputStream(new FileInputStream(tmp));
- }
+ public static boolean deltree(File target) {
+ return deltree(target, null).isEmpty();
+ }
- int orientation;
- try {
- orientation = getExifTransorm(in);
- } catch (Exception e) {
- // no EXIF transform, ok
- orientation = -1;
+ /**
+ * Recursively delete the given {@link File}, which may of course also be a
+ * directory.
+ *
+ * Will collect all {@link File} that cannot be deleted in the given
+ * accumulator.
+ *
+ * @param target
+ * the target to delete
+ * @param errorAcc
+ * the accumulator to use for errors, or NULL to create a new one
+ *
+ * @return the errors accumulator
+ */
+ public static List
- * Note: this code has been found on internet; thank you anonymous coder.
- *