package org.appwork.utils; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; //import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URL; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.logging.Level; import org.appwork.utils.Files.Handler; import org.appwork.utils.ReusableByteArrayOutputStreamPool.ReusableByteArrayOutputStream; import org.appwork.utils.logging.Log; import org.appwork.utils.os.CrossSystem; public class IO { public static void copyFile(final File in, final File out) throws IOException { try { FileInputStream fis = null; FileOutputStream fos = null; FileChannel inChannel = null; FileChannel outChannel = null; if (Log.L.isLoggable(Level.FINEST)) { Log.L.finest("Copy " + in + " to " + out); } try { inChannel = (fis = new FileInputStream(in)).getChannel(); outChannel = (fos = new FileOutputStream(out)).getChannel(); if (CrossSystem.isWindows()) { // magic number for Windows, 64Mb - 32Kb) // On the Windows plateform, you can't copy a file bigger // than // 64Mb, // an Exception in thread "main" java.io.IOException: // Insufficient // system resources exist to complete the requested service // is // thrown. // // For a discussion about this see : // http://forum.java.sun.com/thread.jspa?threadID=439695&messageID=2917510 final int maxCount = 64 * 1024 * 1024 - 32 * 1024; final long size = inChannel.size(); long position = 0; while (position < size) { position += inChannel.transferTo(position, maxCount, outChannel); } } else { inChannel.transferTo(0, inChannel.size(), outChannel); } } catch (final IOException e) { throw e; } finally { try { outChannel.close(); } catch (final Throwable e) { } try { fos.close(); } catch (final Throwable e) { } try { inChannel.close(); } catch (final Throwable e) { } try { fis.close(); } catch (final Throwable e) { } } } catch (IOException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onCopyException(e, in, out); throw e; } catch (RuntimeException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onCopyException(e, in, out); throw e; } catch (Error e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onCopyException(e, in, out); throw e; } } public static String importFileToString(final File file) throws IOException { return IO.importFileToString(file, -1); } public static String importFileToString(final File file, final int maxSize) throws IOException { final byte[] bytes = IO.readFile(file, maxSize); if (bytes == null) { return null; } return new String(bytes, "UTF-8"); } public static void moveTo(final File source, final File dest, final FileFilter filter) throws IOException { final java.util.List<File> files = Files.getFiles(filter, source); // TODO Proper delete for (final File src : files) { final String rel = Files.getRelativePath(source, src); final File file = new File(dest, rel); if (src.isDirectory()) { file.mkdirs(); } else { file.getParentFile().mkdirs(); System.out.println(src + " -> " + file); if (!src.renameTo(file)) { throw new IOException("Could not move file " + src + " to " + file); } } } } public static byte[] readFile(final File ressource) throws IOException { return IO.readFile(ressource, -1); } public static byte[] readFile(final File ressource, final int maxSize) throws IOException { return IO.readURL(ressource.toURI().toURL(), maxSize); } public static String readFileToString(final File file) throws IOException { return IO.readURLToString(file.toURI().toURL()); } public static String readInputStreamToString(final InputStream fis) throws UnsupportedEncodingException, IOException { BufferedReader f = null; try { f = new BufferedReader(new InputStreamReader(fis, "UTF-8")); String line; final StringBuilder ret = new StringBuilder(); final String sep = System.getProperty("line.separator"); while ((line = f.readLine()) != null) { if (ret.length() > 0) { ret.append(sep); } else if (line.startsWith("\uFEFF")) { /* * Workaround for this bug: * http://bugs.sun.com/view_bug.do?bug_id=4508058 * http://bugs.sun.com/view_bug.do?bug_id=6378911 */ line = line.substring(1); } ret.append(line); } return ret.toString(); } catch (IOException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onReadStreamException(e, fis); throw e; } catch (RuntimeException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onReadStreamException(e, fis); throw e; } catch (Error e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onReadStreamException(e, fis); throw e; } finally { try { f.close(); } catch (final Throwable e) { } } } /* * this function reads a line from a bufferedinputstream up to a maxLength. * in case the line is longer than maxLength the rest of the line is read * but not returned * * this function skips emtpy lines */ public static String readLine(final BufferedInputStream is, final byte[] array) throws IOException { Arrays.fill(array, 0, array.length, (byte) 0); int read = 0; int total = 0; int totalString = 0; boolean nextLineReached = false; while (true) { read = is.read(); if (read == -1 && total == 0) { /* EOS */ return null; } if (read == 13 || read == 10) { /* line break found, mark in inputstream */ nextLineReached = true; is.mark(1024); } else if (nextLineReached) { /* new text found */ is.reset(); total--; break; } else if (total < array.length) { /* only write to outputstream if maxlength not reached yet */ array[totalString++] = (byte) read; } total++; } return new String(array, 0, totalString, "UTF-8"); } public static byte[] readStream(final int maxSize, final InputStream input) throws IOException { return IO.readStream(maxSize, input, new ByteArrayOutputStream()); } @SuppressWarnings("resource") public static byte[] readStream(final int maxSize, final InputStream input, final ByteArrayOutputStream baos) throws IOException { ReusableByteArrayOutputStream os = null; try { os = ReusableByteArrayOutputStreamPool.getReusableByteArrayOutputStream(32767); int len; while ((len = input.read(os.getInternalBuffer())) != -1) { if (len > 0) { baos.write(os.getInternalBuffer(), 0, len); if (maxSize > 0 && baos.size() > maxSize) { throw new IOException("Max size exeeded!"); } } } } catch (IOException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onReadStreamException(e, input); throw e; } catch (RuntimeException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onReadStreamException(e, input); throw e; } catch (Error e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onReadStreamException(e, input); throw e; } finally { try { ReusableByteArrayOutputStreamPool.reuseReusableByteArrayOutputStream(os); } catch (final Throwable e) { } try { input.close(); } catch (final Exception e) { } try { baos.close(); } catch (final Throwable e) { } } return baos.toByteArray(); } /** * @param f * @return * @throws IOException */ public static byte[] readURL(final URL f) throws IOException { // TODO Auto-generated method stub return IO.readURL(f, -1); } /** * @param url * @param maxSize * @return * @throws IOException */ public static byte[] readURL(final URL url, final int maxSize) throws IOException { InputStream input = null; try { if (Log.L.isLoggable(Level.FINEST)) { Log.L.finest("Read " + url + " max size: " + maxSize); } input = url.openStream(); return IO.readStream(maxSize, input); } finally { try { input.close(); } catch (final Throwable e) { } } } /** * @param ressourceURL * @return * @throws IOException * @throws UnsupportedEncodingException */ public static String readURLToString(final URL ressourceURL) throws IOException { InputStream fis = null; try { if (Log.L.isLoggable(Level.FINEST)) { Log.L.finest("Read " + ressourceURL); } fis = ressourceURL.openStream(); return IO.readInputStreamToString(fis); } finally { try { fis.close(); } catch (final Throwable e) { } } } public static void writeStringToFile(final File file, final String string) throws IOException { try { if (file == null) { throw new IllegalArgumentException("File is null."); } if (file.exists()) { throw new IllegalArgumentException("File already exists: " + file); } file.createNewFile(); if (!file.isFile()) { throw new IllegalArgumentException("Is not a file: " + file); } if (!file.canWrite()) { throw new IllegalArgumentException("Cannot write to file: " + file); } //FileWriter fw = null; if (Log.L.isLoggable(Level.FINEST)) { Log.L.finest("Write " + file); } final Writer output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); try { output.write(string); } finally { try { output.flush(); } catch (final Throwable e) { } // try { // fw.flush(); // } catch (final Throwable e) { // } try { output.close(); } catch (final Throwable e) { } // try { // fw.close(); // } catch (final Throwable e) { // } } } catch (IOException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onWriteException(e, file, string.getBytes()); throw e; } catch (RuntimeException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onWriteException(e, file, string.getBytes()); throw e; } catch (Error e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onWriteException(e, file, string.getBytes()); throw e; } } private static IOErrorHandler ERROR_HANDLER = null; public static IOErrorHandler getErrorHandler() { return ERROR_HANDLER; } /** * Want to get informed in case of any io problems, set this handler * * @param handler */ public static void setErrorHandler(IOErrorHandler handler) { ERROR_HANDLER = handler; } public static void writeToFile(final File file, final byte[] data) throws IOException { try { if (file == null) { throw new IllegalArgumentException("File is null."); } if (file.exists()) { throw new IllegalArgumentException("File already exists: " + file); } file.createNewFile(); if (!file.isFile()) { throw new IllegalArgumentException("Is not a file: " + file); } if (!file.canWrite()) { throw new IllegalArgumentException("Cannot write to file: " + file); } if (Log.L.isLoggable(Level.FINEST)) { Log.L.finest("Write " + file); } final FileOutputStream out = new FileOutputStream(file); try { out.write(data); } finally { try { out.close(); } catch (final Throwable e) { } } } catch (IOException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onWriteException(e, file, data); throw e; } catch (RuntimeException e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onWriteException(e, file, data); throw e; } catch (Error e) { if (ERROR_HANDLER != null) ERROR_HANDLER.onWriteException(e, file, data); throw e; } } /** * @param file * @param bytes * @throws IOException */ public static void secureWrite(File file, byte[] bytes) throws IOException { File bac = new File(file.getAbsolutePath() + ".bac"); bac.delete(); file.getParentFile().mkdirs(); try { writeToFile(bac, bytes); file.delete(); if (!bac.renameTo(file)) { throw new IOException("COuld not rename " + bac + " to " + file); } } finally { bac.delete(); } } /** * @param dist * @param dist2 * @throws IOException */ public static void copyFolderRecursive(final File src, final File dest) throws IOException { Files.walkThroughStructure(new Handler<IOException>() { @Override public void onFile(File f) throws IOException { String path = Files.getRelativePath(src, f); if (f.isDirectory()) { new File(dest, path).mkdirs(); } else { IO.copyFile(f, new File(dest, path)); } } }, src); } }