我正在尝试将CharSequence
转换为UTF-8编码的byte[]
数组。
我一直有问题,所以我想问stackoverflow的帮助。我想写一个 Java Fiddle 来实现它:
https://www.mycompiler.io/view/3MliN0HgwDD
只是小提琴本身不管用:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.nio.*;
import java.nio.charset;
// The main method must be in a class named "Main".
class Main {
public static byte[] charSequenceToUtf8(final CharSequence input)
{
//char[] chars = new char[input.length];
//for (int i=0; i<input.length; i++)
// chars[i] = input.charAt(i);
CharBuffer charBuffer = CharBuffer.wrap(input);
checkEquals(10, charBuffer.length(), "Charbuffer is wrong length");
Charset cs = Charset.forName("UTF-8");
ByteBuffer byteBuffer = cs.encode(charBuffer);
checkEquals(10, byteBuffer.length(), "byteBuffer is wrong length");
byte[] utf8 = byteBuffer.array();
checkEquals(10, utf8.length, "utf8 bytes is wrong length");
}
public static void checkEquals(int expected, int actual, String message)
{
if (expected == actual)
return;
String sExpected = String.valueOf(expected);
String sActual = String.valueOf(actual);
throw new Exception("Test failed. Expected "+sExpected+", Actual "+sActual+". "+message);
}
public static void main(String[] args) {
test("AAAAAAAAAA"); //ten A's
}
}
java.nio
至少需要Java 7 ref。这就是为什么它在Java 16中不工作的原因:
所以这带来了很多问题:
- 如何将
CharSequence
数组转换为byte[]
数组?1 - 为什么在Java 16中不能使用?
最后,实际的错误是,尝试编码字符串AAAAAAAAA
返回一个11元素的数组:
| 字符序列|UTF-8字节数组|
| --------------|--------------|
| * AA | [65, 65]
|
| “AAA”|[65, 65, 65]
|
| “AAAA”| [65, 65, 65, 65]
|
| “AAAAA”| [65, 65, 65, 65, 65]
|
| * “AAAAAA”| [65, 65, 65, 65, 65, 65]
|
| * “啊啊啊”| [65, 65, 65, 65, 65, 65, 65]
|
| * “啊啊啊啊”| [65, 65, 65, 65, 65, 65, 65, 65]
|
| * “啊啊啊啊啊”| [65, 65, 65, 65, 65, 65, 65, 65, 65]
|
| * “啊啊啊啊啊啊”| [65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0]
|
为什么上面的代码,我从链接的问题中偷来的,失败的是一个10个字符的字符串?
1条答案
按热度按时间wj8zmpe11#
首先,请注意,如果你有一个
String
,那么你可以简单地这样做:或者,即使你有一个
CharSequence
,你也可以这样做:这可能会创建
CharSequence
的String
* 副本 *,如果它还不是String
的话,尽管它应该很快被垃圾收集。但是关于你的问题,你没有考虑
ByteBuffer
的限制(或位置,尽管在这种情况下是0
)。无论出于何种原因,对"AAAAAAAAAA"
进行编码会导致缓冲区的容量为11
,但其限制为10
。但是#array()
方法返回整个后台数组,而不管缓冲区的位置或限制。这意味着在将ByteBuffer
转换为byte[]
时,您需要手动考虑限制(和位置)。例如:
它将输出:
请注意,上面的示例复制了缓冲区的后备数组的一个区域,尽管原始的
ByteBuffer
应该很快被垃圾收集。我能想到的避免复制后台数组的唯一方法是修改代码以直接使用ByteBuffer
(如果只返回后台数组,则会丢失位置/限制信息)。或者我想你可以创建一个 Package 器类。