【问题标题】:ByteBuffer to String in Java [duplicate]Java中的ByteBuffer到String [重复]
【发布时间】:2017-08-31 05:37:03
【问题描述】:

我有这行代码

String s = new String(m_buffer.array());

其中缓冲区是一个字节缓冲区。

有没有一种方法可以将字节缓冲区转换为字符串,而无需分配新的字符串和/或涉及复制 char 数组? (即,有没有办法安全地将 String 的 char[] 值指向 ByteBuffer 的 byte[] hb?)

谢谢

【问题讨论】:

  • 首先byte[]不是char[],其次不是。您应该更担心在不指定编码的情况下从字节创建字符串。一个很好的方法来编写代码,一旦你的默认编码发生变化就会中断。
  • 字符串在 Java 中是不可变的,所以这是不可能的另一个原因。

标签: java bytebuffer


【解决方案1】:

将 ByteBuffer 转换为 String 的一种方法是使用 Charset 来解码字节:

Charset charset = Charset.forName("ISO-8859-1");

ByteBuffer m_buffer = ...;

String text = charset.decode(m_buffer).toString();

解码创建一个CharBuffer,您可以方便地将其转换为String。您可以重用CharSet,它是线程安全的。我不会太担心性能(重新“最快的方式”),除非你在那个领域真的有问题。一般建议,当您想使用 ByteBuffer 时,尽可能晚地进行 to-String 转换,并且仅在需要 String 时进行。

正如 14jbella 所述,字符串是不可变的。无法从不包括复制数据的数组(字符或字节)创建字符串,因为数组是可变的。所以不,不复制就没有办法。

您还应该考虑到,m_buffer.array() 返回ByteBuffer 的内部数组,这可能比缓冲区中存储的实际数据多得多。从该数组创建字符串可能会导致潜在的巨大内存分配,因为数据被复制到新数组中。例如,如果您在代码中的某处使用 256 MB ByteBuffer,并且您从该缓冲区获得名为 m_buffer 的 32 个字节的 slice() 以转换为字符串,则您对 new String(m_buffer.array()) 的调用将分配一个新字节原始支持字节数组大小的数组,即 256 MB,如果需要 GC,这可能不是那么快。

顺便说一句。 new String(byte[]) 在内部使用 CharSet 解码器,将 ByteBuffer 包裹在输入字节数组周围。

【讨论】:

    【解决方案2】:

    Java 的 String 类是不可变的。为了维持这个保证,String 必须有自己对支持它的char[] 的引用,并且没有其他人可以拥有该引用。如果要与ByteBuffer 共享一个数组,String 类不能保证它不会被修改。另外,char和byte在Java中是不一样的。

    【讨论】:

    • 谢谢大家。那么我的方式是将字节缓冲区转换为字符串的“最快方式”吗? (想 StringBuilder 有帮助吗?)
    猜你喜欢
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 2020-03-28
    • 2019-01-08
    • 1970-01-01
    相关资源
    最近更新 更多