IoUtils.java

  1. /*
  2.  * @copyright defined in LICENSE.txt
  3.  */

  4. package hera.util;

  5. import static hera.util.ValidationUtils.assertNotNull;
  6. import static org.slf4j.LoggerFactory.getLogger;

  7. import com.google.common.io.BaseEncoding;
  8. import java.io.ByteArrayOutputStream;
  9. import java.io.Flushable;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.io.OutputStream;
  13. import java.io.Reader;
  14. import java.io.StringWriter;
  15. import java.io.Writer;
  16. import java.security.DigestInputStream;
  17. import java.security.MessageDigest;
  18. import java.security.NoSuchAlgorithmException;
  19. import org.slf4j.Logger;

  20. public class IoUtils {
  21.   protected static final Logger logger = getLogger(IoUtils.class);

  22.   /**
  23.    * Call #flush if possible.
  24.    * <p>
  25.    * Call #flush if the element of {@code flushables} is next:
  26.    * </p>
  27.    * <ul>
  28.    * <li>{@link Flushable}</li>
  29.    * </ul>
  30.    *
  31.    * @param flushable object instances to flush
  32.    */
  33.   public static void tryFlush(final Object... flushable) {
  34.     for (final Object obj : flushable) {
  35.       try {
  36.         if (obj instanceof Flushable) {
  37.           ((Flushable) obj).flush();
  38.         }
  39.       } catch (final Throwable th) {
  40.         logger.trace("Ignore exception: {}", th);
  41.       }
  42.     }
  43.   }

  44.   /**
  45.    * Process streaming.
  46.    *
  47.    * @param in {@link InputStream}
  48.    * @param consumer instance to use streaming
  49.    *
  50.    * @return read bytes
  51.    *
  52.    * @throws IOException If fail to read or process
  53.    */
  54.   public static int stream(final InputStream in, final StreamConsumer consumer) throws Exception {
  55.     assertNotNull(in);

  56.     final byte[] buffer = new byte[1024];
  57.     int readBytes;
  58.     int sum = 0;
  59.     while (0 < (readBytes = in.read(buffer))) {
  60.       consumer.apply(buffer, 0, readBytes);
  61.       sum += readBytes;
  62.     }

  63.     return sum;
  64.   }

  65.   /**
  66.    * Redirect {@code from} to {@code to}.
  67.    *
  68.    * @param from {@link InputStream} to read
  69.    * @param to {@link OutputStream} to write
  70.    *
  71.    * @return the number of bytes to redirect
  72.    *
  73.    * @throws IOException Fail to read or write
  74.    */
  75.   public static int redirect(final InputStream from, final OutputStream to) throws IOException {
  76.     assertNotNull(to);
  77.     try {
  78.       return stream(from, new StreamConsumer() {
  79.         @Override
  80.         public void apply(byte[] bytes, int offset, int length) throws Exception {
  81.           to.write(bytes, offset, length);
  82.         }
  83.       });
  84.     } catch (final Exception e) {
  85.       throw (IOException) e;
  86.     }
  87.   }

  88.   /**
  89.    * Redirect {@code from} to {@code to}.
  90.    *
  91.    * @param from {@link Reader} to read
  92.    * @param to {@link Writer} to write
  93.    *
  94.    * @return the number of bytes to redirect
  95.    *
  96.    * @throws IOException Fail to read or write
  97.    */
  98.   public static int redirect(final Reader from, final Writer to) throws IOException {
  99.     assertNotNull(from);
  100.     assertNotNull(to);

  101.     final char[] buffer = new char[1024];
  102.     int readBytes;
  103.     int sum = 0;
  104.     while (0 < (readBytes = from.read(buffer))) {
  105.       to.write(buffer, 0, readBytes);
  106.       sum += readBytes;
  107.     }

  108.     return sum;
  109.   }

  110.   /**
  111.    * Read from {@code in} and return all bytes.
  112.    *
  113.    * @param in {@link InputStream} to read
  114.    *
  115.    * @return read bytes
  116.    *
  117.    * @throws IOException Fail to read
  118.    */
  119.   public static byte[] from(
  120.       final InputStream in)
  121.       throws IOException {
  122.     final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

  123.     final byte[] bytes = new byte[10000];
  124.     int readBytes;
  125.     while (0 < (readBytes = in.read(bytes))) {
  126.       byteOut.write(bytes, 0, readBytes);
  127.     }
  128.     return byteOut.toByteArray();
  129.   }

  130.   /**
  131.    * Read from {@code reader} and return string.
  132.    *
  133.    * @param reader {@link Reader} to read
  134.    * @return read string
  135.    *
  136.    * @throws IOException Fail to read
  137.    */
  138.   public static String from(
  139.       final Reader reader)
  140.       throws IOException {
  141.     final StringWriter writer = new StringWriter();

  142.     final char[] bytes = new char[10000];
  143.     int readBytes;
  144.     while (0 < (readBytes = reader.read(bytes))) {
  145.       writer.write(bytes, 0, readBytes);
  146.     }
  147.     return writer.toString();
  148.   }

  149.   /**
  150.    * Calculate checksum.
  151.    *
  152.    * @param in {@link InputStream} containing content
  153.    * @return checksum
  154.    * @throws IOException Fail to read content
  155.    * @throws NoSuchAlgorithmException No MD5 algorithm
  156.    */
  157.   public static byte[] getChecksum(final InputStream in)
  158.       throws IOException, NoSuchAlgorithmException {
  159.     final MessageDigest checksumGenerator = MessageDigest.getInstance("MD5");

  160.     final DigestInputStream dis = new DigestInputStream(in, checksumGenerator);
  161.     int readBytes = redirect(dis, new ByteArrayOutputStream());
  162.     logger.debug("{} byte(s) read", readBytes);
  163.     return checksumGenerator.digest();
  164.   }

  165.   /**
  166.    * Calculate checksum as string.
  167.    *
  168.    * @param in {@link InputStream} containing content
  169.    * @return checksum
  170.    * @throws IOException Fail to read content
  171.    * @throws NoSuchAlgorithmException No MD5 algorithm
  172.    */
  173.   public static String getChecksumAsString(final InputStream in)
  174.       throws IOException, NoSuchAlgorithmException {
  175.     final byte[] bytes = getChecksum(in);
  176.     return BaseEncoding.base64().encode(bytes);
  177.   }
  178. }