java获取字符串的大小,以字节为单位进行编码,而不转换为字节[]
我需要知道String
/编码对的大小(以字节为单位),但不能使用getBytes()
方法,因为String
非常大,在byte[]
数组中复制String
会占用大量内存,但更重要的是,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;
}
}
# 1 楼答案
很简单,只需将其写入虚拟输出流:
它不仅简单,而且可能和其他“复杂”答案一样快
# 2 楼答案
番石榴有这样一个实现post:
^{}
# 3 楼答案
使用apache commons库也是一样:
# 4 楼答案
下面是一个显然有效的实现:
输出为:
实际上,我会把
ENCODE_CHUNK
增加到10个字符左右可能比brettw的答案效率略低,但更容易实现
# 5 楼答案
好吧,这太恶心了。我承认这一点,但是JVM隐藏了这些东西,所以我们必须稍微挖掘一下。还有一点汗
首先,我们需要实际的char[],它支持一个字符串而不进行复制。为此,我们必须使用反射来获取“值”字段:
接下来需要实现
java.nio.ByteBuffer
的子类。比如:忽略所有的getter,实现所有的put方法,比如}可能没有被使用
put(byte)
和putChar(char)
等等。在put(byte)
这样的东西内部,将长度增加1,在put(byte[])
内部将长度增加数组长度。了解了?放入的所有内容,都将其大小添加到长度中。但你并没有在ByteBuffer
中存储任何东西,你只是在数数并扔掉,所以没有占用任何空间。如果您对put
方法进行断点设置,您可能会知道实际需要实现哪些方法^例如,{现在是大结局,把它们放在一起: