高效地将Java字符串转换为表示C字符串的空结尾byte[]?(ASCII)

3
我希望将Java中的字符串String str转换为byte[] b,需要满足以下要求:
  • b是一个有效的C字符串(即b.length = str.length() + 1并且b[str.length()] ==0 )。
  • b中的字符是通过将str中的字符转换为8位ASCII字符而获得的。
有没有现成的库函数可以实现这一点,最好是最高效的方法?可惜,str.getBytes("ISO-8859-1")不能满足我的第一个要求...

4
到目前为止,你尝试过哪些不够高效的方法?请展示一些代码。 - Bruno Reis
1
我在询问是否有一个库函数。请参见上面的“最好是一个现有的库函数”。这意味着我正在寻找……一个库函数。很抱歉,你没有耐心阅读整个问题,而是卡在了你精心加斜体的短语上。 - 0xbe5077ed
实际上,我确实读了整个问题。问题在于,正如你所问的那样,你的问题读起来像是:“你好,我需要做一些工作,但我不想做。你能替我做吗?”你似乎并不是在寻找“最有效”的解决方案,也不是在寻找特定的库函数;相反,你似乎只是用这个短语试图隐藏自己和他人面前,你没有任何东西可以展示,你什么都没尝试过。最后,由于你非常、非常新手StackOverflow,也许你只是不知道在提问之前应该先做一些工作,我很友善地提供给你这些信息。 - Bruno Reis
1
有趣的是,Nova能够提供一个出色的答案,而没有任何讽刺或贬低。事实上,我确实做了一些工作,我也没有试图“隐藏”任何东西。只是这个网站上的“一些”人只是在寻找借口来表现得咄咄逼人、粗鲁和比谁都聪明。如果我发布一个截断高位字节并说“天哪,肯定有更好的方法”的for循环,那么我的问题会“少一些需要隐藏”的吗?如果在搜索之后,我除了我提到的str.getBytes()之外没有找到任何其他方法,我该如何用代码表示“毫无头绪”呢? - 0xbe5077ed
它肯定会帮助你更好地提问,或者至少更好地思考你的问题。你明确表示你正在寻找最有效的方法来做这个,也许是通过使用库函数。对于你来说什么是“有效”的?如果你已经有了一个解决方案(正如你在评论中所说),为什么这个解决方案不够“高效”或者“好”?它有哪些问题?现在,对于这些答案,它们比你已有的解决方案更好在哪里?你进行过测量吗?你确定你标记为“接受”的答案确实给出了最有效的解决方案吗?你考虑过JNI吗? - Bruno Reis
注意:您在标题中明确提到了ASCII,但在正文中使用了ISO-8859-1。请知道,ASCII是ISO-8859-1的子集,如果您确实需要ASCII,则应该明确指定而不是ISO-8859-1。 - Joachim Sauer
2个回答

11
// do this once to setup
CharsetEncoder enc = Charset.forName("ISO-8859-1").newEncoder();

// for each string
int len = str.length();
byte b[] = new byte[len + 1];
ByteBuffer bbuf = ByteBuffer.wrap(b);
enc.encode(CharBuffer.wrap(str), bbuf, true);
// you might want to ensure that bbuf.position() == len
b[len] = 0;

这需要分配一对包装器对象,但不会复制字符串字符两次。


请注意,如果转换为UTF-8,则此方法不起作用。enc.encode()返回的字节数可能与UTF-16字符串长度不相等。 - richb
@richb 你说得没错,但问题特别限制在ISO-8859-1编码上。UTF-8是一种可变大小的编码,需要预先计算或悲观分配(CharseEncoder.maxBytesPerChar())。你最好放弃单次分配目标,只使用CharsetEncoder.encode(CharBufffer) - NovaDenizen

7

您可以使用 str.getBytes("ISO-8859-1"),在结尾处稍加技巧:

byte[] stringBytes=str.getBytes("ISO-8859-1");
byte[] ntBytes=new byte[stringBytes.length+1];
System.arraycopy(stringBytes, 0, ntBytes, 0, stringBytes.length);

arraycopy 函数通常可以利用本地技巧和优化,因此速度相对较快。在许多情况下,新数组将使用 null 字节填充未覆盖的部分(基本上只有最后一个字节)。

ntBytes 是你所需的数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接