Hi, It may take a few iterations to get the API settled.
There are other byte sources we may want to consider such as InputStream and ByteBuffer. Comments below. Paul. > On 7 Dec 2016, at 08:32, Vincent Ryan <vincent.x.r...@oracle.com> wrote: > > A hexdump facility has been available for many, many years via an unsupported > class: sun.misc.HexDumpEncoder. > Although that class was always unsupported, it was still accessible. That > accessibility changes with Jigsaw so I’m proposing > a very simple replacement in a new and supported class: java.util.HexDump. > > Thanks. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8170769 > Webrev: http://cr.openjdk.java.net/~vinnie/8170769/webrev.00/ > 55 if (bytes == null) { 56 throw new NullPointerException(); 57 } Objects.requireNonNull 78 * @throws IllegalArgumentException if {@code hexString} has an odd number 79 * of digits 80 * @throws NullPointerException if {@code hexString} is {@code null} 81 */ 82 public static byte[] fromHexString(String hexString) { This should accept a CharSequence, plus also have bounded range equivalent. Also throws IAE if the hexString contains non-convertible characters. 106 /** 107 * Generates a stream of hexadecimal strings, in 16-byte chunks, 108 * from the contents of a binary buffer. 109 * 110 * @param bytes a binary buffer 111 * @return a stream of hexadecimal strings 112 * @throws NullPointerException if {@code bytes} is {@code null} 113 */ 114 public static Stream<String> dumpToStream(byte[] bytes) { 115 if (bytes == null) { 116 throw new NullPointerException(); 117 } 118 return StreamSupport.stream( 119 Spliterators.spliteratorUnknownSize( 120 new HexDumpIterator(bytes), 121 Spliterator.ORDERED | Spliterator.NONNULL), 122 false); 123 } I suspect there is no need for a HexDumpIterator and you can do: return IntStream.range(0, roundUp(bytes.length, 16)).mapToObject(…); and in the map function take care of the trailing bytes based on the byte[] length. That’s potentially simple enough there might be no need for a stream method. Where it gets more complicated is if the source is of unknown size such as InputStream, where the stream returning method probably has more value. Ideally what we want to return is Stream<[Long, String]>, then it’s really easy for others for format, but alas the current form would be ugly and inefficient. So i suspect the dump method has some legs but it’s real value may be for a fully streaming solution. 140 public static String dump(byte[] bytes) { 141 if (bytes == null) { 142 throw new NullPointerException(); 143 } 144 145 int[] count = { -16 }; 146 return dumpToStream(bytes).collect(Collector.of( 147 StringBuilder::new, 148 (stringBuilder, hexString) -> 149 stringBuilder 150 .append(String.format("%08x %s%n", 151 (count[0] += CHUNK_LENGTH), 152 explode(hexString))), 153 StringBuilder::append, 154 StringBuilder::toString)); 155 } The encoding of the count and exploding could also append directly into the main string builder, reducing memory churn. And i think you can also start from IntStream.range(0, roundUp(bytes.length, 16)) avoiding the count state. 192 if (b < ' ' || b > '~') { 193 sb.append(".”); Use ‘.’ 194 } else { 195 sb.append(new String(new byte[]{ b })); Cast the byte to a char instead. 196 }