恐怕我对一个相当过饱和的主题的细节有疑问,我搜索了很多,但找不到一个明确的答案来解决这个特定的明显 - 恕我直言 - 重要的问题:
使用 UTF-8 将 byte[] 转换为 String 时,每个字节(8bit)都变成了 UTF-8 编码的 8 位字符,但在 java 中每个 UTF-8 字符都保存为 16 位字符。那是对的吗?如果是,这意味着每个愚蠢的 java 字符只使用前 8 位,并消耗双倍的内存?这也正确吗?我想知道这种浪费行为是如何被接受的。
有一个 8 位的伪字符串没有什么技巧吗?这实际上会导致更少的内存消耗吗?或者,有没有办法在一个java 16位字符中存储>两个< 8位字符以避免这种内存浪费?
感谢您提供任何令人困惑的答案...
编辑:嗨,谢谢大家的回答。我知道 UTF-8 的可变长度属性。但是,由于我的源是 8 位字节,我理解(显然是错误的)它只需要 8 位 UTF-8 字。UTF-8 转换是否实际上保存了您在 CLI 上执行“cat somebinary”时看到的奇怪符号?我认为 UTF-8 只是以某种方式用于将字节的每个可能的 8 位字映射到 UTF-8 的一个特定的 8 位字。错误的?我考虑过使用 Base64 但这很糟糕,因为它只使用 7 位..
重新制定的问题:有没有更聪明的方法将字节转换为字符串?可能最喜欢的是将 byte[] 转换为 char[],但我仍然有 16 位字。
其他用例信息:
我正在改编Jedis(NoSQL Redis 的 java 客户端)作为 hypergraphDB 的“原始存储层”。所以,jedis是另一个“数据库”的数据库。我的问题是我必须一直为 jedis 提供 byte[] 数据,但在内部,>Redis<(实际的服务器)只处理“二进制安全”字符串。由于 Redis 是用 C 编写的,因此 char 是 8 位长,AFAIK 不是 7 位的 ASCIII。然而,在 Jedis 和 Java 世界中,每个字符的内部长度都是 16 位。我还不明白这段代码,但我想 jedis 然后将这个 java 16 位字符串转换为符合 Redis 的 8 位字符串(([这里] [3])。它说它扩展了 FilterOutputStream。我希望绕过byte[] <-> 字符串转换并使用那个Filteroutputstream ...?)
现在我想知道:如果我必须一直相互转换 byte[] 和 String,数据大小从非常小到可能非常大,在 java 中将每个 8 位字符作为 16 位传递是否会浪费大量内存?