359 lines
14 KiB
Java
359 lines
14 KiB
Java
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
* (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package net.locusworks.common.io;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.io.Reader;
|
|
import java.io.StringWriter;
|
|
import java.io.Writer;
|
|
import java.nio.charset.Charset;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
import net.locusworks.common.Charsets;
|
|
|
|
public class IOUtils {
|
|
|
|
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
|
|
public static final int EOF = -1;
|
|
|
|
/**
|
|
* Gets the contents of an <code>InputStream</code> as a list of Strings,
|
|
* one entry per line, using the specified character encoding.
|
|
* <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, 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
|
|
*/
|
|
public static List<String> readLines(final InputStream stream, final Charset charset) throws IOException {
|
|
final InputStreamReader reader = new InputStreamReader(stream, charset);
|
|
return readLines(reader);
|
|
}
|
|
|
|
/**
|
|
* Gets the contents of a <code>Reader</code> as a list of Strings,
|
|
* one entry per line.
|
|
* <p>
|
|
* This method buffers the input internally, so there is no need to use a
|
|
* <code>BufferedReader</code>.
|
|
*
|
|
* @param input the <code>Reader</code> 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
|
|
*/
|
|
public static List<String> readLines(final Reader input) throws IOException {
|
|
final BufferedReader reader = toBufferedReader(input);
|
|
final List<String> list = new ArrayList<>();
|
|
for(String line = reader.readLine(); line != null; line = reader.readLine()) {
|
|
list.add(line);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
/**
|
|
* Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
|
|
* reader.
|
|
*
|
|
* @param reader the reader to wrap or return (not null)
|
|
* @return the given reader or a new {@link BufferedReader} for the given reader
|
|
* @throws NullPointerException if the input parameter is null
|
|
* @see #buffer(Reader)
|
|
*/
|
|
public static BufferedReader toBufferedReader(final Reader reader) {
|
|
return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
|
|
}
|
|
|
|
/**
|
|
* Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>.
|
|
* <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 byte array
|
|
* @throws NullPointerException if the input is null
|
|
* @throws IOException if an I/O error occurs
|
|
*/
|
|
public static byte[] toByteArray(final InputStream input) throws IOException {
|
|
try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
|
copy(input, output);
|
|
return output.toByteArray();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copies 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
|
|
*/
|
|
public static int copy(final InputStream input, final OutputStream output) throws IOException {
|
|
final long count = copyLarge(input, output);
|
|
if (count > Integer.MAX_VALUE) {
|
|
return -1;
|
|
}
|
|
return (int) count;
|
|
}
|
|
/**
|
|
* Copies bytes from an <code>InputStream</code> to an <code>OutputStream</code> using an internal buffer of the
|
|
* given size.
|
|
* <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 output the <code>OutputStream</code> to write to
|
|
* @param bufferSize the bufferSize used to copy from the input to the output
|
|
* @return the number of bytes copied
|
|
* @throws NullPointerException if the input or output is null
|
|
* @throws IOException if an I/O error occurs
|
|
*/
|
|
public static long copy(final InputStream input, final OutputStream output, final int bufferSize)
|
|
throws IOException {
|
|
return copyLarge(input, output, new byte[bufferSize]);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public static void copy(final InputStream input, final Writer output, final Charset inputEncoding)
|
|
throws IOException {
|
|
final InputStreamReader in = new InputStreamReader(input, inputEncoding.toString());
|
|
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
|
|
*/
|
|
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
|
|
*/
|
|
public static long copyLarge(final Reader input, final Writer output) throws IOException {
|
|
return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
|
|
}
|
|
|
|
/**
|
|
* Copies 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
|
|
*/
|
|
public static long copyLarge(final InputStream input, final OutputStream output)
|
|
throws IOException {
|
|
return copy(input, output, DEFAULT_BUFFER_SIZE);
|
|
}
|
|
|
|
/**
|
|
* Copies 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
|
|
*/
|
|
public static long copyLarge(final InputStream input, final OutputStream output, final byte[] buffer)
|
|
throws IOException {
|
|
long count = 0;
|
|
int n;
|
|
while (EOF != (n = input.read(buffer))) {
|
|
output.write(buffer, 0, n);
|
|
count += n;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public static String toString(final InputStream input, final Charset encoding) throws IOException {
|
|
try (final StringWriter sw = new StringWriter()) {
|
|
copy(input, sw, encoding);
|
|
return sw.toString();
|
|
}
|
|
}
|
|
|
|
public static void writeStringToFile(String fileName, String data) throws IOException {
|
|
writeStringToFile(Paths.get(fileName), data, Charsets.UTF_8);
|
|
}
|
|
|
|
|
|
public static void writeStringToFile(String fileName, String data, Charset charset) throws IOException {
|
|
writeStringToFile(Paths.get(fileName), data, charset);
|
|
}
|
|
|
|
public static void writeStringToFile(Path file, String data) throws IOException {
|
|
writeStringToFile(file, data, Charsets.UTF_8);
|
|
}
|
|
|
|
@Deprecated
|
|
public static void writeStringToFile(File file, String data, Charset charset) throws IOException {
|
|
writeStringToFile(file.toPath(), data, charset);
|
|
}
|
|
|
|
public static void writeStringToFile(Path file, String data, Charset charset) throws IOException {
|
|
try(Writer writer = Files.newBufferedWriter(file, charset)) {
|
|
writer.write(data);
|
|
writer.flush();
|
|
}
|
|
}
|
|
|
|
public static void deleteFile(String fileName) {
|
|
deleteFile(Paths.get(fileName));
|
|
}
|
|
|
|
@Deprecated
|
|
public static void deleteFile(File file) {
|
|
deleteFile(file.toPath());
|
|
}
|
|
|
|
public static void deleteFile(Path file) {
|
|
try {
|
|
Files.deleteIfExists(file);
|
|
} catch (IOException ex) {
|
|
throw new IllegalArgumentException(ex);
|
|
}
|
|
}
|
|
|
|
public static void deleteFiles(String... fileNames) {
|
|
Arrays.asList(fileNames).forEach(file -> deleteFile(file));
|
|
}
|
|
}
|