【发布时间】:2013-11-08 05:49:00
【问题描述】:
我有一种情况,我需要知道String/编码对的大小(以字节为单位),但不能使用getBytes() 方法,因为1)String 非常大并且复制了String在 byte[] 数组中将使用大量内存,但更重要的是 2) getBytes() 根据 String 的长度分配 byte[] 数组 * 每个字符的最大可能字节数。因此,如果我有一个带有 1.5B 字符和 UTF-16 编码的 String,getBytes() 将尝试分配一个 3GB 数组并失败,因为数组限制为 2^32 - X 字节(X 是特定于 Java 版本的)。
那么 - 有没有办法直接从 String 对象计算 String/编码对的字节大小?
更新:
这是 jtahlborn 回答的一个有效实现:
private class CountingOutputStream extends OutputStream {
int total;
@Override
public void write(int i) {
throw new RuntimeException("don't use");
}
@Override
public void write(byte[] b) {
total += b.length;
}
@Override public void write(byte[] b, int offset, int len) {
total += len;
}
}
【问题讨论】:
-
字节长度取决于您的目标编码。例如,“test”.getBytes("UTF-8") 是 4 个字节,但 "test".getBytes("UTF-16") 是 10 个字节(是的,10 个,试试看)。所以你需要澄清一下你的问题。
-
我要补充一点,它还取决于您正在编码的代码点(“字符”)。例如,在 UTF-16 中,某些代码点使用 1 个代码单元,而其他代码点使用 2 个(代码单元为 16 位长)。 UTF-8 每个字符可以占用 1 到 4 个字节。
-
@brettw 对不起,如果我很密集,但是是的,你的评论是问题的关键:给定一个字符串和一个编码,编码字符串需要多少字节?重读这个问题,这对我来说似乎很清楚 - 你对改写它有什么建议吗?
-
@Francis 上面的评论也适用于您的评论,尽我所能。
-
getByte不会创建一个比它需要的更大的数组。它为给定的字符串创建一个正确大小的数组。它不会创建长度为“字符串长度 * 每个字符的最大可能字节数”的数组。而string.length()不返回字符串中的字符数,它返回代码单元的数量。对于 UTF-16,一个代码单元是 16 位,每个字符的代码单元数是 1 或 2,这取决于字符。因此,要么我不明白你问题中的第二点,要么你的假设不正确。