将 ASCII 字节 [] 转换为字符串

2022-09-02 12:01:33

我正在尝试将包含ASCII字符的byte[]传递给log4j,以使用明显的表示形式登录到文件中。当我简单地传入 byt[] 时,它当然被视为一个对象,日志非常无用。当我尝试使用它们转换为字符串时,我的应用程序的性能减半。new String(byte[] data)

我怎样才能有效地将它们传入,而不会产生将它们转换为字符串的大约30us时间损失。

另外,为什么转换它们需要这么长时间?

谢谢。

编辑

我应该补充一点,我在这里选择延迟 - 是的,30us确实有所作为!此外,这些数组从~100一直到几千字节不等。


答案 1

ASCII 是为数不多的可以转换为 UTF16 的编码之一,无需算术或表查找,因此可以手动转换:

String convert(byte[] data) {
    StringBuilder sb = new StringBuilder(data.length);
    for (int i = 0; i < data.length; ++ i) {
        if (data[i] < 0) throw new IllegalArgumentException();
        sb.append((char) data[i]);
    }
    return sb.toString();
}

但要确保它确实ASCII,否则你最终会得到垃圾。


答案 2

您要做的是延迟对byte[]数组的处理,直到log4j决定它实际上想要记录消息。这样,您可以在调试级别记录它,例如,在测试时,然后在生产期间禁用它。例如,您可以:

final byte[] myArray = ...;
Logger.getLogger(MyClass.class).debug(new Object() {
    @Override public String toString() {
        return new String(myArray);
    }
});

现在,除非您实际记录数据,否则无需支付速度损失,因为在log4j确定它实际记录消息之前,不会调用toString方法!

现在我不确定你所说的“明显的表示”是什么意思,所以我假设你的意思是通过将字节重新解释为默认字符编码来转换为字符串。现在,如果您正在处理二进制数据,这显然是毫无价值的。在这种情况下,我建议使用Arrays.toString(byte[])沿着

[54, 23, 65, ...]

推荐