/* * Copyright (c) 2006 and onwards Makoto Yui * * Licensed 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. */ /* * Copyright 2001-2004 The Apache Software Foundation * * Licensed 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 btree4j.utils.io; import java.io.Closeable; import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutput; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * IO related utilities. */ public final class IOUtils { private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; private IOUtils() {} public static void writeInt(final int v, final OutputStream out) throws IOException { out.write((v >>> 24) & 0xFF); out.write((v >>> 16) & 0xFF); out.write((v >>> 8) & 0xFF); out.write((v >>> 0) & 0xFF); } /** * @return may be negative value when EOF is detected. */ public static int readInt(final InputStream in) throws IOException { final int ch1 = in.read(); final int ch2 = in.read(); final int ch3 = in.read(); final int ch4 = in.read(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } public static int readUnsignedIntOrEOF(final InputStream in) throws IOException { final int ch1 = in.read(); if (ch1 == -1) { return -1; } final int ch2 = in.read(); final int ch3 = in.read(); final int ch4 = in.read(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } public static void writeChar(final char v, final OutputStream out) throws IOException { out.write(0xff & (v >> 8)); out.write(0xff & v); } public static void writeChar(final char v, final FastByteArrayOutputStream out) { out.write(0xff & (v >> 8)); out.write(0xff & v); } public static char readChar(final InputStream in) throws IOException { final int a = in.read(); final int b = in.read(); return (char) ((a << 8) | (b & 0xff)); } public static void readFully(final InputStream in, final byte[] b, int offset, int len) throws IOException { do { final int bytesRead = in.read(b, offset, len); if (bytesRead < 0) { throw new EOFException(); } len -= bytesRead; offset += bytesRead; } while (len != 0); } public static void readFully(final InputStream in, final byte[] b) throws IOException { readFully(in, b, 0, b.length); } public static int readLoop(final InputStream in, final byte[] b, final int off, final int len) throws IOException { int total = 0; for (;;) { final int got = in.read(b, off + total, len - total); if (got < 0) { return (total == 0) ? -1 : total; } else { total += got; if (total == len) { return total; } } } } public static int copy(InputStream input, OutputStream output) throws IOException { final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int count = 0; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; } public static int copy(Reader input, Writer output) throws IOException { final char[] buffer = new char[DEFAULT_BUFFER_SIZE]; int count = 0; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; } public static void copy(String input, OutputStream output) throws IOException { final StringReader in = new StringReader(input); final OutputStreamWriter out = new OutputStreamWriter(output); copy(in, out); // Unless anyone is planning on rewriting OutputStreamWriter, we have to flush here. out.flush(); } /** * Serialize given InputStream as String. */ public static String toString(InputStream input) throws IOException { final FastMultiByteArrayOutputStream output = new FastMultiByteArrayOutputStream(); copy(input, output); return output.toString(); } public static String toString(InputStream input, String cs) throws IOException { final FastMultiByteArrayOutputStream output = new FastMultiByteArrayOutputStream(); copy(input, output); return output.toString(cs); } public static String toString(Reader input) throws IOException { final StringWriter sw = new StringWriter(); copy(input, sw); return sw.toString(); } @Deprecated public static void getBytes(final List<byte[]> srcLst, final byte[] dest) { int pos = 0; for (byte[] bytes : srcLst) { final int len = bytes.length; System.arraycopy(bytes, 0, dest, pos, len); pos += len; } } public static byte[] getBytes(final InputStream in) throws IOException { FastByteArrayOutputStream out = new FastByteArrayOutputStream(4096); copy(in, out); return out.toByteArray(); } public static void closeQuietly(final Closeable channel) { if (channel != null) { try { channel.close(); } catch (IOException e) { ; } } } public static void closeQuietly(final Closeable... channels) { for (Closeable c : channels) { if (c != null) { try { c.close(); } catch (IOException e) { ; } } } } public static void closeAndRethrow(final Exception e, final Closeable... channels) throws IllegalStateException { closeQuietly(channels); throw new IllegalStateException(e); } /** * @param delay delay in milliseconds before task is to be executed. */ public static void schduleCloseQuietly(final Timer timer, final long delay, final Closeable... channels) { if (delay == 0) { closeQuietly(channels); return; } final TimerTask cancel = new TimerTask() { @Override public void run() { closeQuietly(channels); } }; timer.schedule(cancel, delay); } public static void schduleCloseQuietly(final ScheduledExecutorService sched, final int delay, final AtomicInteger activeCount, final Closeable... channels) { if (delay == 0) { closeQuietly(channels); return; } final Runnable cancel = new Runnable() { public void run() { if (activeCount.get() < 1) { closeQuietly(channels); } } }; sched.schedule(cancel, delay, TimeUnit.MILLISECONDS); } public static void writeBytes(@Nullable final byte[] b, final DataOutput out) throws IOException { if (b == null) { out.writeInt(-1); return; } final int len = b.length; out.writeInt(len); out.write(b, 0, len); } public static void writeBytes(@Nullable final byte[] b, final FastBufferedOutputStream out) throws IOException { if (b == null) { writeInt(-1, out); return; } final int len = b.length; writeInt(len, out); out.write(b, 0, len); } @Nullable public static byte[] readBytes(final DataInput in) throws IOException { final int len = in.readInt(); if (len == -1) { return null; } final byte[] b = new byte[len]; in.readFully(b, 0, len); return b; } @Nullable public static byte[] readBytes(final FastBufferedInputStream in) throws IOException { final int len = readInt(in); if (len == -1) { return null; } final byte[] b = new byte[len]; in.read(b, 0, len); return b; } public static void writeString(@Nullable final String s, final ObjectOutputStream out) throws IOException { writeString(s, (DataOutput) out); } public static void writeString(@Nullable final String s, final DataOutputStream out) throws IOException { writeString(s, (DataOutput) out); } public static void writeString(@Nullable final String s, final DataOutput out) throws IOException { if (s == null) { out.writeInt(-1); return; } final int len = s.length(); out.writeInt(len); for (int i = 0; i < len; i++) { int v = s.charAt(i); out.writeChar(v); } } public static void writeString(@Nullable final String s, final OutputStream out) throws IOException { if (s == null) { writeInt(-1, out); return; } final int len = s.length(); writeInt(len, out); for (int i = 0; i < len; i++) { char c = s.charAt(i); writeChar(c, out); } } @Nullable public static String readString(@Nonnull final ObjectInputStream in) throws IOException { return readString((DataInput) in); } @Nullable public static String readString(@Nonnull final DataInputStream in) throws IOException { return readString((DataInput) in); } @Nullable public static String readString(@Nonnull final DataInput in) throws IOException { final int len = in.readInt(); if (len == -1) { return null; } final char[] ch = new char[len]; for (int i = 0; i < len; i++) { ch[i] = in.readChar(); } return new String(ch); } @Nullable public static String readString(@Nonnull final InputStream in) throws IOException { final int len = readInt(in); if (len == -1) { return null; } final char[] ch = new char[len]; for (int i = 0; i < len; i++) { ch[i] = readChar(in); } return new String(ch); } }