public static HexDump hexDump(final InputStream inputStream,
                                  final Charset charset,
                                  final long byteOffset,
                                  final int maxHexDumpLines) throws IOException {

        Objects.requireNonNull(inputStream);
        Objects.requireNonNull(charset);
        // We want to start at an offset that is at the start of a line
        long effectiveByteOffset = byteOffset == 0
                ? 0
                : ((long) ((double) byteOffset / HexDump.MAX_BYTES_PER_LINE)) * HexDump.MAX_BYTES_PER_LINE;

        final CharsetDecoder charsetDecoder = getCharsetDecoder(charset);
        if (effectiveByteOffset > 0) {
            final long lenSkipped = inputStream.skip(effectiveByteOffset);
            if (lenSkipped < effectiveByteOffset) {
                throw new RuntimeException(LogUtil.message("Failed to skip to byte offset {}. Not enough data",
                        effectiveByteOffset));
            }
        }

        // zero based for simpler maths
        int lineOffset = (int) (effectiveByteOffset / HexDump.MAX_BYTES_PER_LINE);
        int lineCount = 0;
        final HexDumpBuilder hexDumpBuilder = new HexDumpBuilder();
        while (lineCount < maxHexDumpLines) {
            int len = decodeHexDumpLine(inputStream, charsetDecoder, hexDumpBuilder, lineOffset);
            if (len == -1) {
                break;
            }
            lineOffset++;
            lineCount++;
        }

        return hexDumpBuilder.build(charset);
    }
Produces a hex dump similar to the linux xxd binary.

@param inputStream     The stream to dump as hex
@param charset         The charset to decode single bytes with. Even if a multibyte charset
                       is supplied bytes will only be decoded individually.
@param maxHexDumpLines The max number of line of hex dump output. A full line contains 32 bytes.
@return
@throws IOException
stroom-util/src/main/java/stroom/util/string/HexDumpUtil.java