code: public static long copyBytesAndGenerateCRC(InputStream in, OutputStream out, 
        int buffSize, boolean close, IOThrottler throttler) 
      throws IOException {
      
      PrintStream ps = out instanceof PrintStream ? (PrintStream)out : null;
      byte buf[] = new byte[buffSize];
      Checksum sum = new NativeCrc32();
      sum.reset();
      try {
        if (throttler != null) {
          throttler.throttle((long) buffSize);
        }
        int bytesRead = in.read(buf);
        while (bytesRead >= 0) {
          sum.update(buf, 0, bytesRead);
          out.write(buf, 0, bytesRead);
          if ((ps != null) && ps.checkError()) {
            throw new IOException("Unable to write to output stream.");
          }
          if (throttler != null) {
            throttler.throttle((long) buffSize);
          }
          bytesRead = in.read(buf);
        }
      } finally {
        if(close) {
          out.close();
          in.close();
        }
      }
      return sum.getValue();
    }
docs: Copies from one stream to another and generate CRC checksum.
  @param in InputStrem to read from
  @param out OutputStream to write to
  @param buffSize the size of the buffer
  @param close whether or not close the InputStream and
  @param throttler IO Throttler
  OutputStream at the end. The streams are closed in the finally clause.
  @return CRC checksum