|
@@ -0,0 +1,360 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * Copyright (C) 2018 Tran Le Duy
|
|
|
|
|
+ *
|
|
|
|
|
+ * 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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+package com.itant.metrowc.tool.file;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+import java.io.File;
|
|
|
|
|
+import java.io.FileInputStream;
|
|
|
|
|
+import java.io.FileOutputStream;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.io.InputStream;
|
|
|
|
|
+import java.io.InputStreamReader;
|
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
|
+import java.io.Reader;
|
|
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
|
|
+import java.io.Writer;
|
|
|
|
|
+import java.nio.charset.Charset;
|
|
|
|
|
+import java.nio.charset.UnsupportedCharsetException;
|
|
|
|
|
+
|
|
|
|
|
+public class IOUtils {
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Represents the end-of-file (or stream).
|
|
|
|
|
+ *
|
|
|
|
|
+ * @since 2.5 (made public)
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final int EOF = -1;
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The default buffer size ({@value}) to use for
|
|
|
|
|
+ * {@link #copyLarge(InputStream, OutputStream)}
|
|
|
|
|
+ * and
|
|
|
|
|
+ * {@link #copyLarge(Reader, Writer)}
|
|
|
|
|
+ */
|
|
|
|
|
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
|
|
|
|
|
+ /**
|
|
|
|
|
+ * The default buffer size to use for the skip() methods.
|
|
|
|
|
+ */
|
|
|
|
|
+ private static final int SKIP_BUFFER_SIZE = 2048;
|
|
|
|
|
+ // read toString
|
|
|
|
|
+ //-----------------------------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ public static void copyNotIfExistAndClose(InputStream input, File outputFile) throws IOException {
|
|
|
|
|
+ if (outputFile.exists()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ outputFile.getParentFile().mkdirs();
|
|
|
|
|
+ FileOutputStream output = new FileOutputStream(outputFile);
|
|
|
|
|
+ copy(input, output);
|
|
|
|
|
+ output.close();
|
|
|
|
|
+ try {
|
|
|
|
|
+ input.close();
|
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static String toString(File file) throws IOException {
|
|
|
|
|
+ FileInputStream input = new FileInputStream(file);
|
|
|
|
|
+ String s = toString(input);
|
|
|
|
|
+ input.close();
|
|
|
|
|
+ return s;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void writeAndClose(String content, File file) throws IOException {
|
|
|
|
|
+ FileOutputStream output = new FileOutputStream(file);
|
|
|
|
|
+ output.write(content.getBytes());
|
|
|
|
|
+ output.close();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Gets the contents of an <code>InputStream</code> as a String
|
|
|
|
|
+ * using the default character encoding of the platform.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedInputStream</code>.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>InputStream</code> to read from
|
|
|
|
|
+ * @return the requested String
|
|
|
|
|
+ * @throws NullPointerException if the input is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @deprecated 2.5 use {@link #toString(InputStream, Charset)} instead
|
|
|
|
|
+ */
|
|
|
|
|
+ @Deprecated
|
|
|
|
|
+ public static String toString(final InputStream input) throws IOException {
|
|
|
|
|
+ return toString(input, Charset.forName("UTF-8"));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static String toString(final InputStream input, final String encoding) throws IOException {
|
|
|
|
|
+ return toString(input, Charset.forName(encoding));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Gets the contents of an <code>InputStream</code> as a String
|
|
|
|
|
+ * using the specified character encoding.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedInputStream</code>.
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>InputStream</code> 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
|
|
|
|
|
+ * @since 2.3
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String toString(final InputStream input, final Charset encoding) throws IOException {
|
|
|
|
|
+ final StringBuilderWriter sw = new StringBuilderWriter();
|
|
|
|
|
+ try {
|
|
|
|
|
+ copy(input, sw, encoding);
|
|
|
|
|
+ return sw.toString();
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ sw.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copies bytes from an <code>InputStream</code> to chars on a
|
|
|
|
|
+ * <code>Writer</code> using the specified character encoding.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedInputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method uses {@link InputStreamReader}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>InputStream</code> to read from
|
|
|
|
|
+ * @param output the <code>Writer</code> to write to
|
|
|
|
|
+ * @param inputEncoding the encoding to use for the input stream, null means platform default
|
|
|
|
|
+ * @throws NullPointerException if the input or output is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @since 2.3
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void copy(final InputStream input, final Writer output, final Charset inputEncoding)
|
|
|
|
|
+ throws IOException {
|
|
|
|
|
+ final InputStreamReader in = new InputStreamReader(input, inputEncoding);
|
|
|
|
|
+ copy(in, output);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copies chars from a <code>Reader</code> to a <code>Writer</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedReader</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * Large streams (over 2GB) will return a chars copied value of
|
|
|
|
|
+ * <code>-1</code> after the copy has completed since the correct
|
|
|
|
|
+ * number of chars cannot be returned as an int. For large streams
|
|
|
|
|
+ * use the <code>copyLarge(Reader, Writer)</code> method.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>Reader</code> to read from
|
|
|
|
|
+ * @param output the <code>Writer</code> to write to
|
|
|
|
|
+ * @return the number of characters copied, or -1 if > Integer.MAX_VALUE
|
|
|
|
|
+ * @throws NullPointerException if the input or output is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @since 1.1
|
|
|
|
|
+ */
|
|
|
|
|
+ public static int copy(final Reader input, final Writer output) throws IOException {
|
|
|
|
|
+ final long count = copyLarge(input, output);
|
|
|
|
|
+ if (count > Integer.MAX_VALUE) {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ return (int) count;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedReader</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>Reader</code> to read from
|
|
|
|
|
+ * @param output the <code>Writer</code> 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 1.3
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long copyLarge(final Reader input, final Writer output) throws IOException {
|
|
|
|
|
+ return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method uses the provided buffer, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedReader</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>Reader</code> to read from
|
|
|
|
|
+ * @param output the <code>Writer</code> to write to
|
|
|
|
|
+ * @param buffer the buffer to be used for the copy
|
|
|
|
|
+ * @return the number of characters copied
|
|
|
|
|
+ * @throws NullPointerException if the input or output is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @since 2.2
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long copyLarge(final Reader input, final Writer output, final char[] buffer) throws IOException {
|
|
|
|
|
+ long count = 0;
|
|
|
|
|
+ int n;
|
|
|
|
|
+ while (EOF != (n = input.read(buffer))) {
|
|
|
|
|
+ output.write(buffer, 0, n);
|
|
|
|
|
+ count += n;
|
|
|
|
|
+ }
|
|
|
|
|
+ return count;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
|
|
|
|
|
+ * <code>OutputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedInputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>InputStream</code> to read from
|
|
|
|
|
+ * @param output the <code>OutputStream</code> 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 1.3
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long copyLarge(InputStream input, OutputStream output)
|
|
|
|
|
+ throws IOException {
|
|
|
|
|
+ return copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
|
|
|
|
|
+ * <code>OutputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method uses the provided buffer, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedInputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>InputStream</code> to read from
|
|
|
|
|
+ * @param output the <code>OutputStream</code> to write to
|
|
|
|
|
+ * @param buffer the buffer to use for the copy
|
|
|
|
|
+ * @return the number of bytes copied
|
|
|
|
|
+ * @throws NullPointerException if the input or output is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @since 2.2
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long copyLarge(InputStream input, OutputStream output, byte[] buffer)
|
|
|
|
|
+ throws IOException {
|
|
|
|
|
+ long count = 0;
|
|
|
|
|
+ int n = 0;
|
|
|
|
|
+ while (EOF != (n = input.read(buffer))) {
|
|
|
|
|
+ output.write(buffer, 0, n);
|
|
|
|
|
+ count += n;
|
|
|
|
|
+ }
|
|
|
|
|
+ return count;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // copy from InputStream
|
|
|
|
|
+ //-----------------------------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Copy bytes from an <code>InputStream</code> to an
|
|
|
|
|
+ * <code>OutputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method buffers the input internally, so there is no need to use a
|
|
|
|
|
+ * <code>BufferedInputStream</code>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * Large streams (over 2GB) will return a bytes copied value of
|
|
|
|
|
+ * <code>-1</code> after the copy has completed since the correct
|
|
|
|
|
+ * number of bytes cannot be returned as an int. For large streams
|
|
|
|
|
+ * use the <code>copyLarge(InputStream, OutputStream)</code> method.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param input the <code>InputStream</code> to read from
|
|
|
|
|
+ * @param output the <code>OutputStream</code> to write to
|
|
|
|
|
+ * @return the number of bytes copied, or -1 if > Integer.MAX_VALUE
|
|
|
|
|
+ * @throws NullPointerException if the input or output is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @since 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;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Writes chars from a <code>String</code> to bytes on an
|
|
|
|
|
+ * <code>OutputStream</code> using the default character encoding of the
|
|
|
|
|
+ * platform.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method uses {@link String#getBytes()}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data the <code>String</code> to write, null ignored
|
|
|
|
|
+ * @param output the <code>OutputStream</code> to write to
|
|
|
|
|
+ * @throws NullPointerException if output is null
|
|
|
|
|
+ * @throws IOException if an I/O error occurs
|
|
|
|
|
+ * @since 1.1
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void write(String data, OutputStream output)
|
|
|
|
|
+ throws IOException {
|
|
|
|
|
+ write(data, output, Charset.forName("UTF-8"));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Writes chars from a <code>String</code> to bytes on an
|
|
|
|
|
+ * <code>OutputStream</code> using the specified character encoding.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method uses {@link String#getBytes(String)}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data the <code>String</code> to write, null ignored
|
|
|
|
|
+ * @param output the <code>OutputStream</code> 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 2.3
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void write(String data, OutputStream output, Charset encoding) throws IOException {
|
|
|
|
|
+ if (data != null) {
|
|
|
|
|
+ output.write(data.getBytes(encoding));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Writes chars from a <code>String</code> to bytes on an
|
|
|
|
|
+ * <code>OutputStream</code> using the specified character encoding.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * Character encoding names can be found at
|
|
|
|
|
+ * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * This method uses {@link String#getBytes(String)}.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param data the <code>String</code> to write, null ignored
|
|
|
|
|
+ * @param output the <code>OutputStream</code> 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
|
|
|
|
|
+ * @throws UnsupportedCharsetException thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
|
|
|
|
|
+ * supported.
|
|
|
|
|
+ * @since 1.1
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void write(String data, OutputStream output, String encoding)
|
|
|
|
|
+ throws IOException {
|
|
|
|
|
+ write(data, output, Charset.forName(encoding));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|