/* * Iris is a World Generator for Minecraft Bukkit Servers * Copyright (c) 2021 Arcane Arts (Volmit Software) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.volmit.iris.util; import com.volmit.iris.Iris; import java.io.*; import java.nio.charset.StandardCharsets; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.function.Consumer; import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @SuppressWarnings("ALL") public class IO { /** * The Unix directory separator character. */ public static final char DIR_SEPARATOR_UNIX = '/'; /** * The Windows directory separator character. */ public static final char DIR_SEPARATOR_WINDOWS = '\\'; /** * The system directory separator character. */ public static final char DIR_SEPARATOR = File.separatorChar; /** * The Unix line separator string. */ public static final String LINE_SEPARATOR_UNIX = "\n"; /** * The Windows line separator string. */ public static final String LINE_SEPARATOR_WINDOWS = "\r\n"; /** * The system line separator string. */ public static final String LINE_SEPARATOR; /** * The default buffer size to use. */ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String decompress(String gz) throws IOException { ByteArrayInputStream bin = new ByteArrayInputStream(Base64.getUrlDecoder().decode(gz)); GZIPInputStream gzi = new GZIPInputStream(bin); ByteArrayOutputStream boas = new ByteArrayOutputStream(); IO.fullTransfer(gzi, boas, 256); gzi.close(); return boas.toString(); } public static byte[] sdecompress(String compressed) throws IOException { ByteArrayInputStream bin = new ByteArrayInputStream(Base64.getUrlDecoder().decode(compressed)); GZIPInputStream gzi = new GZIPInputStream(bin); ByteArrayOutputStream boas = new ByteArrayOutputStream(); IO.fullTransfer(gzi, boas, 256); gzi.close(); return boas.toByteArray(); } public static String encode(byte[] data) { return Base64.getUrlEncoder().encodeToString(data); } public static byte[] decode(String u) { return Base64.getUrlDecoder().decode(u); } public static String hash(String b) { try { MessageDigest d = MessageDigest.getInstance("SHA-256"); return bytesToHex(d.digest(b.getBytes(StandardCharsets.UTF_8))); } catch (NoSuchAlgorithmException e) { Iris.reportError(e); e.printStackTrace(); } return "¯\\_(ツ)_/¯"; } public static String hash(File b) { try { MessageDigest d = MessageDigest.getInstance("SHA-256"); DigestInputStream din = new DigestInputStream(new FileInputStream(b), d); fullTransfer(din, new VoidOutputStream(), 8192); din.close(); return bytesToHex(din.getMessageDigest().digest()); } catch (Throwable e) {Iris.reportError(e); e.printStackTrace(); } return "¯\\_(ツ)_/¯"; } public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars).toUpperCase(); } /** * Transfers the length of the buffer amount of data from the input stream to * the output stream * * @param in the input * @param out the output * @return the actual transfered amount * @throws IOException shit happens */ public static int transfer(InputStream in, OutputStream out, byte[] buffer) throws IOException { int r = in.read(buffer); if (r != -1) { out.write(buffer, 0, r); } return r; } /** * Transfers the length of the buffer amount of data from the input stream to * the output stream * * @param in the input * @param out the output * @param targetBuffer the buffer and size to use * @param totalSize the total amount to transfer * @return the actual transfered amount * @throws IOException shit happens */ public static long transfer(InputStream in, OutputStream out, int targetBuffer, long totalSize) throws IOException { long total = totalSize; long wrote = 0; byte[] buf = new byte[targetBuffer]; int r = 0; while ((r = in.read(buf, 0, (int) (total < targetBuffer ? total : targetBuffer))) != -1) { total -= r; out.write(buf, 0, r); wrote += r; if (total <= 0) { break; } } return wrote; } /** * Fully move data from a finite inputstream to an output stream using a buffer * size of 8192. This does NOT close streams. * * @param in * @param out * @return total size transfered * @throws IOException */ public static long fillTransfer(InputStream in, OutputStream out) throws IOException { return fullTransfer(in, out, 8192); } public static void deleteUp(File f) { if (f.exists()) { f.delete(); if (f.getParentFile().list().length == 0) { deleteUp(f.getParentFile()); } } } /** * Fully move data from a finite inputstream to an output stream using a given * buffer size. This does NOT close streams. * * @param in the input stream to read from * @param out the output stream to write to * @param bufferSize the target buffer size * @return total size transfered * @throws IOException shit happens */ public static long fullTransfer(InputStream in, OutputStream out, int bufferSize) throws IOException { long wrote = 0; byte[] buf = new byte[bufferSize]; int r = 0; while ((r = in.read(buf)) != -1) { out.write(buf, 0, r); wrote += r; } return wrote; } /** * Recursive delete (deleting folders) * * @param f the file to delete (and subfiles if folder) */ public static void delete(File f) { if (f == null || !f.exists()) { return; } if (f.isDirectory()) { for (File i : f.listFiles()) { delete(i); } } f.delete(); } public static long size(File file) { long s = 0; if (file.exists()) { if (file.isDirectory()) { for (File i : file.listFiles()) { s += size(i); } } else { s += file.length(); } } return s; } public static long count(File file) { long s = 0; if (file.exists()) { if (file.isDirectory()) { for (File i : file.listFiles()) { s += count(i); } } else { s++; } } return s; } public static long transfer(InputStream in, OutputStream out, byte[] buf, int totalSize) throws IOException { long total = totalSize; long wrote = 0; int r = 0; while ((r = in.read(buf, 0, (int) (total < buf.length ? total : buf.length))) != -1) { total -= r; out.write(buf, 0, r); wrote += r; if (total <= 0) { break; } } return wrote; } public static void readEntry(File zipfile, String entryname, Consumer v) throws IOException { ZipFile file = new ZipFile(zipfile); Throwable x = null; try { Enumeration entries = file.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entryname.equals(entry.getName())) { InputStream in = file.getInputStream(entry); v.accept(in); } } } catch (Exception ex) {Iris.reportError(ex); x = ex.getCause(); } finally { file.close(); } if (x != null) { throw new IOException("Failed to read zip entry, however it has been closed safely.", x); } } public static void writeAll(File f, Object c) throws IOException { f.getParentFile().mkdirs(); PrintWriter pw = new PrintWriter(new FileWriter(f)); pw.println(c.toString()); pw.close(); } public static String readAll(File f) throws IOException { FileReader fr; try { fr = new FileReader(f); } catch (IOException e) {Iris.reportError(e); throw e; } BufferedReader bu = new BufferedReader(fr); StringBuilder c = new StringBuilder(); String l = ""; while ((l = bu.readLine()) != null) { c.append(l).append("\n"); } bu.close(); return c.toString(); } public static String readAll(InputStream in) throws IOException { BufferedReader bu = new BufferedReader(new InputStreamReader(in)); StringBuilder c = new StringBuilder(); String l = ""; while ((l = bu.readLine()) != null) { c.append(l).append("\n"); } bu.close(); return c.toString(); } /** * Implements the same behaviour as the "touch" utility on Unix. It creates a * new file with size 0 or, if the file exists already, it is opened and closed * without modifying it, but updating the file date and time. * * @param file the File to touch * @throws IOException If an I/O problem occurs */ public static void touch(File file) throws IOException { if (!file.exists()) { OutputStream out = new FileOutputStream(file); out.close(); } file.setLastModified(System.currentTimeMillis()); } /** * Copies a file to a new location preserving the file date. *

* This method copies the contents of the specified source file to the specified * destination file. The directory holding the destination file is created if it * does not exist. If the destination file exists, then this method will * overwrite it. * * @param srcFile an existing file to copy, must not be null * @param destFile the new file, must not be null * @throws NullPointerException if source or destination is null * @throws IOException if source or destination is invalid * @throws IOException if an IO error occurs during copying */ public static void copyFile(File srcFile, File destFile) throws IOException { copyFile(srcFile, destFile, true); } /** * Copies a file to a new location. *

* This method copies the contents of the specified source file to the specified * destination file. The directory holding the destination file is created if it * does not exist. If the destination file exists, then this method will * overwrite it. * * @param srcFile an existing file to copy, must not be null * @param destFile the new file, must not be null * @param preserveFileDate true if the file date of the copy should be the same as the * original * @throws NullPointerException if source or destination is null * @throws IOException if source or destination is invalid * @throws IOException if an IO error occurs during copying */ public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { if (srcFile == null) { throw new NullPointerException("Source must not be null"); } if (destFile == null) { throw new NullPointerException("Destination must not be null"); } if (!srcFile.exists()) { throw new FileNotFoundException("Source '" + srcFile + "' does not exist"); } if (srcFile.isDirectory()) { throw new IOException("Source '" + srcFile + "' exists but is a directory"); } if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) { throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same"); } if (destFile.getParentFile() != null && !destFile.getParentFile().exists()) { if (!destFile.getParentFile().mkdirs()) { throw new IOException("Destination '" + destFile + "' directory cannot be created"); } } if (destFile.exists() && !destFile.canWrite()) { throw new IOException("Destination '" + destFile + "' exists but is read-only"); } doCopyFile(srcFile, destFile, preserveFileDate); } /** * Internal copy file method. * * @param srcFile the validated source file, not null * @param destFile the validated destination file, not null * @param preserveFileDate whether to preserve the file date * @throws IOException if an error occurs */ private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException { if (destFile.exists() && destFile.isDirectory()) { throw new IOException("Destination '" + destFile + "' exists but is a directory"); } FileInputStream input = new FileInputStream(srcFile); try { FileOutputStream output = new FileOutputStream(destFile); try { IO.copy(input, output); } finally { output.close(); } } finally { input.close(); } if (srcFile.length() != destFile.length()) { throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'"); } if (preserveFileDate) { destFile.setLastModified(srcFile.lastModified()); } } // ----------------------------------------------------------------------- /** * Unconditionally close an Reader. *

* Equivalent to {@link Reader#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param input the Reader to close, may be null or already closed */ public static void closeQuietly(Reader input) { try { if (input != null) { input.close(); } } catch (IOException e) {Iris.reportError(e); // ignore } } /** * Unconditionally close a Writer. *

* Equivalent to {@link Writer#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param output the Writer to close, may be null or already closed */ public static void closeQuietly(Writer output) { try { if (output != null) { output.close(); } } catch (IOException e) {Iris.reportError(e); // ignore } } /** * Unconditionally close an InputStream. *

* Equivalent to {@link InputStream#close()}, except any exceptions will be * ignored. This is typically used in finally blocks. * * @param input the InputStream to close, may be null or already closed */ public static void closeQuietly(InputStream input) { try { if (input != null) { input.close(); } } catch (IOException e) {Iris.reportError(e); // ignore } } /** * Unconditionally close an OutputStream. *

* Equivalent to {@link OutputStream#close()}, except any exceptions will be * ignored. This is typically used in finally blocks. * * @param output the OutputStream to close, may be null or already closed */ public static void closeQuietly(OutputStream output) { try { if (output != null) { output.close(); } } catch (IOException e) {Iris.reportError(e); // ignore } } // read toByteArray // ----------------------------------------------------------------------- /** * Get the contents of an InputStream as a byte[]. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param input the InputStream to read from * @return the requested byte array * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs */ public static byte[] toByteArray(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); copy(input, output); return output.toByteArray(); } /** * Get the contents of a Reader as a byte[] using the * default character encoding of the platform. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. * * @param input the Reader to read from * @return the requested byte array * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs */ public static byte[] toByteArray(Reader input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); copy(input, output); return output.toByteArray(); } /** * Get the contents of a Reader as a byte[] using the * specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. * * @param input the Reader to read from * @param encoding the encoding to use, null means platform default * @return the requested byte array * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static byte[] toByteArray(Reader input, String encoding) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); copy(input, output, encoding); return output.toByteArray(); } /** * Get the contents of a String as a byte[] using the * default character encoding of the platform. *

* This is the same as {@link String#getBytes()}. * * @param input the String to convert * @return the requested byte array * @deprecated Use {@link String#getBytes()} */ public static byte[] toByteArray(String input) { return input.getBytes(); } // read char[] // ----------------------------------------------------------------------- /** * Get the contents of an InputStream as a character array using * the default character encoding of the platform. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param is the InputStream to read from * @return the requested character array * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static char[] toCharArray(InputStream is) throws IOException { CharArrayWriter output = new CharArrayWriter(); copy(is, output); return output.toCharArray(); } /** * Get the contents of an InputStream as a character array using * the specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param is the InputStream to read from * @param encoding the encoding to use, null means platform default * @return the requested character array * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static char[] toCharArray(InputStream is, String encoding) throws IOException { CharArrayWriter output = new CharArrayWriter(); copy(is, output, encoding); return output.toCharArray(); } /** * Get the contents of a Reader as a character array. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. * * @param input the Reader to read from * @return the requested character array * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static char[] toCharArray(Reader input) throws IOException { CharArrayWriter sw = new CharArrayWriter(); copy(input, sw); return sw.toCharArray(); } // read toString // ----------------------------------------------------------------------- /** * Get the contents of an InputStream as a String using the default * character encoding of the platform. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param input the InputStream to read from * @return the requested String * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs */ public static String toString(InputStream input) throws IOException { StringWriter sw = new StringWriter(); copy(input, sw); return sw.toString(); } /** * Get the contents of an InputStream as a String using the * specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param input the InputStream to read from * @param encoding the encoding to use, null means platform default * @return the requested String * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs */ public static String toString(InputStream input, String encoding) throws IOException { StringWriter sw = new StringWriter(); copy(input, sw, encoding); return sw.toString(); } /** * Get the contents of a Reader as a String. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. * * @param input the Reader to read from * @return the requested String * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs */ public static String toString(Reader input) throws IOException { StringWriter sw = new StringWriter(); copy(input, sw); return sw.toString(); } /** * Get the contents of a byte[] as a String using the default * character encoding of the platform. * * @param input the byte array to read from * @return the requested String * @deprecated Use {@link String#String(byte[])} */ public static String toString(byte[] input) { return new String(input); } /** * Get the contents of a byte[] as a String using the specified * character encoding. *

* Character encoding names can be found at * IANA. * * @param input the byte array to read from * @param encoding the encoding to use, null means platform default * @return the requested String * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs (never occurs) * @deprecated Use {@link String#String(byte[], String)} */ public static String toString(byte[] input, String encoding) throws IOException { if (encoding == null) { return new String(input); } else { return new String(input, encoding); } } // readLines // ----------------------------------------------------------------------- /** * Get the contents of an InputStream as a list of Strings, one * entry per line, using the default character encoding of the platform. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param input the InputStream to read from, not null * @return the list of Strings, never null * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static List readLines(InputStream input) throws IOException { InputStreamReader reader = new InputStreamReader(input); return readLines(reader); } /** * Get the contents of an InputStream as a list of Strings, one * entry per line, using the specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param input the InputStream to read from, not null * @param encoding the encoding to use, null means platform default * @return the list of Strings, never null * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static List readLines(InputStream input, String encoding) throws IOException { if (encoding == null) { return readLines(input); } else { InputStreamReader reader = new InputStreamReader(input, encoding); return readLines(reader); } } /** * Get the contents of a Reader as a list of Strings, one entry per * line. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. * * @param input the Reader to read from, not null * @return the list of Strings, never null * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static List readLines(Reader input) throws IOException { BufferedReader reader = new BufferedReader(input); List list = new ArrayList(); String line = reader.readLine(); while (line != null) { list.add(line); line = reader.readLine(); } return list; } // ----------------------------------------------------------------------- /** * Convert the specified string to an input stream, encoded as bytes using the * default character encoding of the platform. * * @param input the string to convert * @return an input stream * @since Commons IO 1.1 */ public static InputStream toInputStream(String input) { byte[] bytes = input.getBytes(); return new ByteArrayInputStream(bytes); } /** * Convert the specified string to an input stream, encoded as bytes using the * specified character encoding. *

* Character encoding names can be found at * IANA. * * @param input the string to convert * @param encoding the encoding to use, null means platform default * @return an input stream * @throws IOException if the encoding is invalid * @since Commons IO 1.1 */ public static InputStream toInputStream(String input, String encoding) throws IOException { byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes(); return new ByteArrayInputStream(bytes); } // write byte[] // ----------------------------------------------------------------------- /** * Writes bytes from a byte[] to an OutputStream. * * @param data the byte array to write, do not modify during output, null ignored * @param output the OutputStream to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(byte[] data, OutputStream output) throws IOException { if (data != null) { output.write(data); } } /** * Writes bytes from a byte[] to chars on a Writer * using the default character encoding of the platform. *

* This method uses {@link String#String(byte[])}. * * @param data the byte array to write, do not modify during output, null ignored * @param output the Writer to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(byte[] data, Writer output) throws IOException { if (data != null) { output.write(new String(data)); } } /** * Writes bytes from a byte[] to chars on a Writer * using the specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method uses {@link String#String(byte[], String)}. * * @param data the byte array to write, do not modify during output, null ignored * @param output the Writer to write to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(byte[] data, Writer output, String encoding) throws IOException { if (data != null) { if (encoding == null) { write(data, output); } else { output.write(new String(data, encoding)); } } } // write char[] // ----------------------------------------------------------------------- /** * Writes chars from a char[] to a Writer using the * default character encoding of the platform. * * @param data the char array to write, do not modify during output, null ignored * @param output the Writer to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(char[] data, Writer output) throws IOException { if (data != null) { output.write(data); } } /** * Writes chars from a char[] to bytes on an * OutputStream. *

* This method uses {@link String#String(char[])} and {@link String#getBytes()}. * * @param data the char array to write, do not modify during output, null ignored * @param output the OutputStream to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(char[] data, OutputStream output) throws IOException { if (data != null) { output.write(new String(data).getBytes()); } } /** * Writes chars from a char[] to bytes on an * OutputStream using the specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method uses {@link String#String(char[])} and * {@link String#getBytes(String)}. * * @param data the char array to write, do not modify during output, null ignored * @param output the OutputStream to write to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(char[] data, OutputStream output, String encoding) throws IOException { if (data != null) { if (encoding == null) { write(data, output); } else { output.write(new String(data).getBytes(encoding)); } } } // write String // ----------------------------------------------------------------------- /** * Writes chars from a String to a Writer. * * @param data the String to write, null ignored * @param output the Writer to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(String data, Writer output) throws IOException { if (data != null) { output.write(data); } } /** * Writes chars from a String to bytes on an * OutputStream using the default character encoding of the * platform. *

* This method uses {@link String#getBytes()}. * * @param data the String to write, null ignored * @param output the OutputStream to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(String data, OutputStream output) throws IOException { if (data != null) { output.write(data.getBytes()); } } /** * Writes chars from a String to bytes on an * OutputStream using the specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method uses {@link String#getBytes(String)}. * * @param data the String to write, null ignored * @param output the OutputStream to write to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(String data, OutputStream output, String encoding) throws IOException { if (data != null) { if (encoding == null) { write(data, output); } else { output.write(data.getBytes(encoding)); } } } // write StringBuffer // ----------------------------------------------------------------------- /** * Writes chars from a StringBuffer to a Writer. * * @param data the StringBuffer to write, null ignored * @param output the Writer to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(StringBuffer data, Writer output) throws IOException { if (data != null) { output.write(data.toString()); } } /** * Writes chars from a StringBuffer to bytes on an * OutputStream using the default character encoding of the * platform. *

* This method uses {@link String#getBytes()}. * * @param data the StringBuffer to write, null ignored * @param output the OutputStream to write to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(StringBuffer data, OutputStream output) throws IOException { if (data != null) { output.write(data.toString().getBytes()); } } /** * Writes chars from a StringBuffer to bytes on an * OutputStream using the specified character encoding. *

* Character encoding names can be found at * IANA. *

* This method uses {@link String#getBytes(String)}. * * @param data the StringBuffer to write, null ignored * @param output the OutputStream to write to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void write(StringBuffer data, OutputStream output, String encoding) throws IOException { if (data != null) { if (encoding == null) { write(data, output); } else { output.write(data.toString().getBytes(encoding)); } } } // writeLines // ----------------------------------------------------------------------- /** * Writes the toString() value of each item in a collection to an * OutputStream line by line, using the default character encoding * of the platform and the specified line ending. * * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @param output the OutputStream to write to, not null, not closed * @throws NullPointerException if the output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void writeLines(Collection lines, String lineEnding, OutputStream output) throws IOException { if (lines == null) { return; } if (lineEnding == null) { lineEnding = LINE_SEPARATOR; } for (Iterator it = lines.iterator(); it.hasNext(); ) { Object line = it.next(); if (line != null) { output.write(line.toString().getBytes()); } output.write(lineEnding.getBytes()); } } /** * Writes the toString() value of each item in a collection to an * OutputStream line by line, using the specified character * encoding and the specified line ending. *

* Character encoding names can be found at * IANA. * * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @param output the OutputStream to write to, not null, not closed * @param encoding the encoding to use, null means platform default * @throws NullPointerException if the output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void writeLines(Collection lines, String lineEnding, OutputStream output, String encoding) throws IOException { if (encoding == null) { writeLines(lines, lineEnding, output); } else { if (lines == null) { return; } if (lineEnding == null) { lineEnding = LINE_SEPARATOR; } for (Iterator it = lines.iterator(); it.hasNext(); ) { Object line = it.next(); if (line != null) { output.write(line.toString().getBytes(encoding)); } output.write(lineEnding.getBytes(encoding)); } } } /** * Writes the toString() value of each item in a collection to a * Writer line by line, using the specified line ending. * * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @param writer the Writer to write to, not null, not closed * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void writeLines(Collection lines, String lineEnding, Writer writer) throws IOException { if (lines == null) { return; } if (lineEnding == null) { lineEnding = LINE_SEPARATOR; } for (Iterator it = lines.iterator(); it.hasNext(); ) { Object line = it.next(); if (line != null) { writer.write(line.toString()); } writer.write(lineEnding); } } // copy from InputStream // ----------------------------------------------------------------------- /** * Copy bytes from an InputStream to an OutputStream. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. *

* Large streams (over 2GB) will return a bytes copied value of -1 * after the copy has completed since the correct number of bytes cannot be * returned as an int. For large streams use the * copyLarge(InputStream, OutputStream) method. * * @param input the InputStream to read from * @param output the OutputStream to write to * @return the number of bytes copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @throws ArithmeticException if the byte count is too large * @since Commons IO 1.1 */ public static int copy(InputStream input, OutputStream output) throws IOException { long count = copyLarge(input, output); if (count > Integer.MAX_VALUE) { return -1; } return (int) count; } /** * Copy bytes from a large (over 2GB) InputStream to an * OutputStream. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. * * @param input the InputStream to read from * @param output the OutputStream to write to * @return the number of bytes copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.3 */ public static long copyLarge(InputStream input, OutputStream output) throws IOException { byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; long count = 0; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; } /** * Copy bytes from an InputStream to chars on a Writer * using the default character encoding of the platform. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. *

* This method uses {@link InputStreamReader}. * * @param input the InputStream to read from * @param output the Writer to write to * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void copy(InputStream input, Writer output) throws IOException { InputStreamReader in = new InputStreamReader(input); copy(in, output); } /** * Copy bytes from an InputStream to chars on a Writer * using the specified character encoding. *

* This method buffers the input internally, so there is no need to use a * BufferedInputStream. *

* Character encoding names can be found at * IANA. *

* This method uses {@link InputStreamReader}. * * @param input the InputStream to read from * @param output the Writer to write to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void copy(InputStream input, Writer output, String encoding) throws IOException { if (encoding == null) { copy(input, output); } else { InputStreamReader in = new InputStreamReader(input, encoding); copy(in, output); } } // copy from Reader // ----------------------------------------------------------------------- /** * Copy chars from a Reader to a Writer. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. *

* Large streams (over 2GB) will return a chars copied value of -1 * after the copy has completed since the correct number of chars cannot be * returned as an int. For large streams use the * copyLarge(Reader, Writer) method. * * @param input the Reader to read from * @param output the Writer to write to * @return the number of characters copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @throws ArithmeticException if the character count is too large * @since Commons IO 1.1 */ public static int copy(Reader input, Writer output) throws IOException { long count = copyLarge(input, output); if (count > Integer.MAX_VALUE) { return -1; } return (int) count; } /** * Copy chars from a large (over 2GB) Reader to a * Writer. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. * * @param input the Reader to read from * @param output the Writer to write to * @return the number of characters copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.3 */ public static long copyLarge(Reader input, Writer output) throws IOException { char[] buffer = new char[DEFAULT_BUFFER_SIZE]; long count = 0; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; } /** * Copy chars from a Reader to bytes on an * OutputStream using the default character encoding of the * platform, and calling flush. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. *

* Due to the implementation of OutputStreamWriter, this method performs a * flush. *

* This method uses {@link OutputStreamWriter}. * * @param input the Reader to read from * @param output the OutputStream to write to * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void copy(Reader input, OutputStream output) throws IOException { OutputStreamWriter out = new OutputStreamWriter(output); copy(input, out); // have to flush here. out.flush(); } /** * Copy chars from a Reader to bytes on an * OutputStream using the specified character encoding, and calling * flush. *

* This method buffers the input internally, so there is no need to use a * BufferedReader. *

* Character encoding names can be found at * IANA. *

* Due to the implementation of OutputStreamWriter, this method performs a * flush. *

* This method uses {@link OutputStreamWriter}. * * @param input the Reader to read from * @param output the OutputStream to write to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static void copy(Reader input, OutputStream output, String encoding) throws IOException { if (encoding == null) { copy(input, output); } else { OutputStreamWriter out = new OutputStreamWriter(output, encoding); copy(input, out); // we have to flush here. out.flush(); } } // content equals // ----------------------------------------------------------------------- /** * Compare the contents of two Streams to determine if they are equal or not. *

* This method buffers the input internally using * BufferedInputStream if they are not already buffered. * * @param input1 the first stream * @param input2 the second stream * @return true if the content of the streams are equal or they both don't * exist, false otherwise * @throws NullPointerException if either input is null * @throws IOException if an I/O error occurs */ public static boolean contentEquals(InputStream input1, InputStream input2) throws IOException { if (!(input1 instanceof BufferedInputStream)) { input1 = new BufferedInputStream(input1); } if (!(input2 instanceof BufferedInputStream)) { input2 = new BufferedInputStream(input2); } int ch = input1.read(); while (-1 != ch) { int ch2 = input2.read(); if (ch != ch2) { return false; } ch = input1.read(); } int ch2 = input2.read(); return (ch2 == -1); } /** * Compare the contents of two Readers to determine if they are equal or not. *

* This method buffers the input internally using BufferedReader if * they are not already buffered. * * @param input1 the first reader * @param input2 the second reader * @return true if the content of the readers are equal or they both don't * exist, false otherwise * @throws NullPointerException if either input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 */ public static boolean contentEquals(Reader input1, Reader input2) throws IOException { if (!(input1 instanceof BufferedReader)) { input1 = new BufferedReader(input1); } if (!(input2 instanceof BufferedReader)) { input2 = new BufferedReader(input2); } int ch = input1.read(); while (-1 != ch) { int ch2 = input2.read(); if (ch != ch2) { return false; } ch = input1.read(); } int ch2 = input2.read(); return (ch2 == -1); } static { // avoid security issues StringWriter buf = new StringWriter(4); PrintWriter out = new PrintWriter(buf); out.println(); LINE_SEPARATOR = buf.toString(); } }