如何“打印”处理不可打印值的字节数组

时间:2018-05-07 18:04:05

标签: java arrays string representation

我在这个论坛上看到了很多有点相关的问题和答案,但没有找到解决我问题的任何问题。

这个想法很简单:

(这是使用Java编程语言 - 我目前仅限于使用Java 7)

接收字节数组(表示任何内容:某种有线格式,某种形式的编码数据,带有嵌入“文本”的二进制数据等)。我希望能够以下列形式打印数组:

  1. 作为十六进制字符串
  2. as“printable”text
  3. 第一种情况部分是出于调试原因,但也可能用于非调试模式。第二种情况纯粹是出于调试原因,可以与其他信息来源进行人工比较。

    我认为我有第一种情况的解决方案,但我正在努力解决第二种情况。

    显然,字节数组可能包含以不同方式呈现的不可打印字符或字符。如何“打印”数组以便表示所有字节?我可以提供的一个很好的模拟是UNIX od命令,其中od -ah以十六进制格式显示二进制数据以及ASCII字符。在这种情况下,通常使用点(.)代替不可打印或控制字符。

    我不需要它具体看起来像od推出的那样,但是希望能够显示数据,以便至少可以看到可打印的字符,其余的用某种形式表示占位符。此外,我不想删除不可打印的字符,因为这会给出误导性的数据表示。

    如果有人有关于如何实现这一目标的信息,我将非常感激。

3 个答案:

答案 0 :(得分:1)

试试#2:

String original = new String(bytes);
String printable = original.replaceAll("\\P{Print}", ".")); //Or any other character instead of "." you want

它使用POSIX printable character class

如果需要Unicode支持,请使用utf-8字符集参数创建String,并使用UNICODE_CHARACTER_CLASS标志构造Pattern并使用与上面相同的正则表达式。

答案 1 :(得分:0)

嗯,Arrays.toString()对你有用吗?

public class PrintBytes {
   public static void main( String[] args ) {
      byte[] test = { 1, 2, 3, 0, (byte)0xFF, (byte)0xFE };
      String s = Arrays.toString( test );
      System.out.println( s );

   }
}

输出:

run:
[1, 2, 3, 0, -1, -2]
BUILD SUCCESSFUL (total time: 0 seconds)

它不是十六进制,但它是一种可用的有线格式。

答案 2 :(得分:0)

为什么不使用DatatypeConverter,这里有两个数组的例子。单词“ hello”的第一个被发明,第二个被发明。

import java.nio.charset.StandardCharsets;
import javax.xml.bind.DatatypeConverter;

public class MainTest {

    public static void main(String[] args) {
        // Something printable
        String hello = "hello";
        byte[] printable = hello.getBytes(StandardCharsets.UTF_8); 
        System.out.println("Printable: " + new String(printable, StandardCharsets.UTF_8));

        // Something not printable
        byte[] notPrintable = { (byte)-156, (byte)190, (byte)56, (byte)-29, (byte)1};

        System.out.println("NotPrintable: " + new String(notPrintable, StandardCharsets.UTF_8));

        // With DatatypeConverter.printBase64Binary you can get a String printable from any byte[]
        final String printableString = DatatypeConverter.printBase64Binary(printable);
        final String notPrintableString = DatatypeConverter.printBase64Binary(notPrintable);

        System.out.println("Printable string with DatatypeConverter: " + printableString);
        System.out.println("Not printable string with DatatypeConverter: " + notPrintableString);

        byte[] otherPrintable = DatatypeConverter.parseBase64Binary(printableString);
        byte[] otherNotPrintable = DatatypeConverter.parseBase64Binary(notPrintableString);

        // And the best point is that you can revert it
        final String otherHello = new String(otherPrintable, StandardCharsets.UTF_8);
        final String strangeString = new String(otherNotPrintable, StandardCharsets.UTF_8);

        System.out.println("Other Hello: " + otherHello);
        System.out.println("Strange String: " + strangeString);
    }

}

这是输出

Printable: hello
NotPrintable: d�8�
Printable string with DatatypeConverter: aGVsbG8=
Not printable string with DatatypeConverter: ZL444wE=
Other Hello: hello
Strange String: d�8�

编辑:DatatypeConverter对Java7和Java8有效,请看Java 11 package javax.xml.bind does not exist