edu.umd.cs.findbugs.io.IO Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spotbugs Show documentation
Show all versions of spotbugs Show documentation
SpotBugs: Because it's easy!
/*
* FindBugs - Find bugs in Java programs
* Copyright (C) 2003,2004 University of Maryland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Copyright (C) 2003 William Pugh
// http://www.cs.umd.edu/~pugh
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
package edu.umd.cs.findbugs.io;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import javax.annotation.CheckForNull;
import javax.annotation.WillClose;
import javax.annotation.WillNotClose;
import edu.umd.cs.findbugs.annotations.CheckReturnValue;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.util.Util;
public class IO {
static ThreadLocal myByteBuf = new ThreadLocal() {
@Override
protected byte[] initialValue() {
return new byte[4096];
}
};
static ThreadLocal myCharBuf = new ThreadLocal() {
@Override
protected char[] initialValue() {
return new char[4096];
}
};
public static byte[] readAll(@WillClose InputStream in) throws IOException {
try {
ByteArrayOutputStream byteSink = new ByteArrayOutputStream();
copy(in, byteSink);
return byteSink.toByteArray();
} finally {
close(in);
}
}
static byte[] copyOf(byte[] original, int newLength) {
byte[] copy = new byte[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
public static byte[] readAll(@WillClose InputStream in, int size) throws IOException {
try {
if (size == 0) {
throw new IllegalArgumentException();
}
byte[] result = new byte[size];
int pos = 0;
while (true) {
int sz;
while ((sz = in.read(result, pos, size - pos)) > 0) {
pos += sz;
}
if (pos < size) {
return copyOf(result, pos);
}
int nextByte = in.read();
if (nextByte == -1) {
return result;
}
size = size * 2 + 500;
result = copyOf(result, size);
result[pos++] = (byte) nextByte;
}
} finally {
close(in);
}
}
public static String readAll(Reader reader) throws IOException {
BufferedReader r = new BufferedReader(reader);
StringWriter w = new StringWriter();
copy(r, w);
return w.toString();
}
public static long copy(@WillNotClose InputStream in, @WillNotClose OutputStream out) throws IOException {
return copy(in, out, Long.MAX_VALUE);
}
public static long copy(Reader in, Writer out) throws IOException {
return copy(in, out, Long.MAX_VALUE);
}
public static long copy(@WillNotClose InputStream in, @WillNotClose OutputStream out, long maxBytes)
throws IOException {
long total = 0;
int sz = 0;
byte buf[] = myByteBuf.get();
while (maxBytes > 0 && (sz = in.read(buf, 0, (int) Math.min(maxBytes, buf.length))) > 0) {
total += sz;
maxBytes -= sz;
out.write(buf, 0, sz);
}
return total;
}
public static long copy(Reader in, Writer out, long maxChars)
throws IOException {
long total = 0;
int sz;
char buf[] = myCharBuf.get();
while (maxChars > 0 && (sz = in.read(buf, 0, (int) Math.min(maxChars, buf.length))) > 0) {
total += sz;
maxChars -= sz;
out.write(buf, 0, sz);
}
return total;
}
/**
* Close given AutoCloseable instance, ignoring any resulting exception.
*
*/
public static void close(@CheckForNull AutoCloseable c) {
if (c == null) {
return;
}
try {
c.close();
} catch (Exception e) {
// Ignore
}
}
/**
* Close given Closeable instance, ignoring any resulting exception.
*
*/
public static void close(@CheckForNull Closeable c) {
close((AutoCloseable) c);
}
/**
* Close given InputStream, ignoring any resulting exception.
*
* @param inputStream
* the InputStream to close; may be null (in which case nothing
* happens)
*/
public static void close(@CheckForNull InputStream inputStream) {
if (inputStream == null) {
return;
}
try {
inputStream.close();
} catch (IOException e) {
// Ignore
}
}
/**
* Close given OutputStream, ignoring any resulting exception.
*
* @param outputStream
* the OutputStream to close; may be null (in which case nothing
* happens)
*/
public static void close(@CheckForNull OutputStream outputStream) {
if (outputStream == null) {
return;
}
try {
outputStream.close();
} catch (IOException e) {
// Ignore
}
}
/**
* Provide a skip fully method. Either skips the requested number of bytes
* or throws an IOException;
*
* @param in
* The input stream on which to perform the skip
* @param bytes
* Number of bytes to skip
* @throws EOFException
* if we reach EOF and still need to skip more bytes
* @throws IOException
* if in.skip throws an IOException
*/
public static void skipFully(InputStream in, long bytes) throws IOException {
if (bytes < 0) {
throw new IllegalArgumentException("Can't skip " + bytes + " bytes");
}
long remaining = bytes;
while (remaining > 0) {
long skipped = in.skip(remaining);
if (skipped <= 0) {
throw new EOFException("Reached EOF while trying to skip a total of " + bytes);
}
remaining -= skipped;
}
}
public static boolean verifyURL(URL u) {
if (u == null) {
return false;
}
InputStream i = null;
try {
URLConnection uc = openNonCachedConnection(u);
i = uc.getInputStream();
int firstByte = i.read();
i.close();
return firstByte >= 0;
}
catch (Exception e) {
return false;
} finally {
Util.closeSilently(i);
}
}
/**
* When URL Connection uses cache, it may keep file handler. This method open connection without caching to avoid
* file handler leak.
*
* @return opened {@link URLConnection} which does not use cache to load data
* @see related GitHub issue
*/
@CheckReturnValue
@NonNull
public static URLConnection openNonCachedConnection(@NonNull URL u) throws IOException {
URLConnection uc = u.openConnection();
if (uc instanceof JarURLConnection) {
uc.setUseCaches(false);
}
return uc;
}
/**
* When URL Connection uses cache, it may keep file handler. This method open connection without caching to avoid
* file handler leak.
*
* @return opened {@link URLConnection} which does not use cache to load data
* @see related GitHub issue
*/
@CheckReturnValue
@NonNull
public static InputStream openNonCachedStream(@NonNull URL u) throws IOException {
return openNonCachedConnection(u).getInputStream();
}
}