Java 如何在不丢失信息的情况下保存字符串字节?

Java 如何在不丢失信息的情况下保存字符串字节?,java,string,int,byte,bitset,Java,String,Int,Byte,Bitset,我正在开发一个JPEG解码器(我正处于哈夫曼阶段),我想将二进制字符串写入一个文件。 例如,假设我们有: String huff=“0001000100010101000100100”; 我尝试将其转换为整数,将其除以8并保存为整数表示,因为我无法写入位: huff.split((?您可能想看看UTF-8算法,因为它正是您想要的。它存储大量数据,同时丢弃零,保留相关数据,并对其进行编码以占用更少的磁盘空间 适用于:Java版本7+ UTF-8是一种可变宽度字符编码,能够使用一到四个8位字节对

我正在开发一个JPEG解码器(我正处于哈夫曼阶段),我想将二进制字符串写入一个文件。 例如,假设我们有:

String huff=“0001000100010101000100100”;
我尝试将其转换为整数,将其除以8并保存为整数表示,因为我无法写入位:


huff.split((?您可能想看看UTF-8算法,因为它正是您想要的。它存储大量数据,同时丢弃零,保留相关数据,并对其进行编码以占用更少的磁盘空间

适用于:Java版本7+

UTF-8是一种可变宽度字符编码,能够使用一到四个8位字节对Unicode中的所有1112064[nb 1]有效代码点进行编码。[nb 2]该编码由Unicode标准定义,最初由Ken Thompson和Rob Pike设计。[1][2]该名称源自Unicode(或通用编码字符集)转换格式–8位。[3]

它是为与ASCII向后兼容而设计的。具有较低数值(通常出现频率较高)的代码点使用较少的字节进行编码。Unicode的前128个字符(与ASCII一一对应)使用与ASCII具有相同二进制值的单个字节进行编码,因此有效的ASCII文本是有效的F-8编码的Unicode。由于将非ASCII代码点编码为UTF-8时不会出现ASCII字节,因此UTF-8在大多数以特殊方式解释某些ASCII字符的编程和文档语言中使用是安全的,例如文件名中的“/”(斜杠)、“转义序列中的\”(反斜杠)和printf中的“%”

二进制
11110000 10010000 10001101 10001000
在UTF-8中变成
F0 90 8D 88
。由于您将其存储为文本,因此您需要将其从存储32个字符变为存储8个字符。由于这是一种众所周知且设计良好的编码,您可以轻松地将其反转。所有的数学运算都为您完成

您的示例
0001001010100010101000001000
(或者更确切地说
0000001 0010100 0101010 00100100
)转换为
*$
(我的机器上有两个无法打印的字符)。这是二进制的UTF-8编码。我错误地使用了另一个站点,该站点使用了我输入的数据作为十进制而不是二进制

对于UTF-8的真正好的解释以及它如何应用于答案:

编辑:

我把这个问题作为一种减少存储值所需的字符量的方法,这是一种编码。UTF-8是一种编码。以“非标准”的方式使用,OP可以使用UTF-8以更短的格式对0和1的字符串进行编码。这就是这个答案的相关性


如果将字符串联在一起,则可以轻松地从4x8位(32位)转换为8x8位(64位),并编码一个大到9223372036854775807的值。

您的示例是,您有字符串
“10010”
,您需要字符串
“00010010”“
。也就是说,您需要将此字符串左键填充为零。请注意,由于您将多次调用的结果连接到一个循环中的
Integer.ToBinarysting
,因此在连接这些字符串之前,您需要将这些字符串左键填充到循环中

while((enter = in.read()) != -1) {
    String binary = Integer.toBinaryString(enter);
    // left-pad to length 8
    binary = ("00000000" + binary).substring(binary.length());
    code += binary;
}

这不会“输”信息,从某种意义上说,你知道丢失的位都是零。你需要的只是用零填充结果。@kaya3好的,但是当我试图读取文件时,我怎么知道我有一些零,我需要填充结果?你总是需要填充结果。左填充意味着从左填充到特定长度;你的所需的长度是8,因此如果字符串的长度已经是8,左填充将不会改变它。@kaya3我编辑了我的问题,因为我认为左填充不是解决方案:(用这样的字符串实现哈夫曼编码对性能来说绝对是一场灾难。不仅速度慢,而且灾难级别慢。这与问题无关。问题中的字符串只包含字符
'0'
'1'
@kaya3,UTF-8是将二进制数据压缩成更小字节块的一种方法。不,UTF-8是一种对文本数据进行编码的方法。二进制数据可以用一种简单的方法以每字节8位进行编码,当然,如果你想象数据代表文本,你就再也做不到比这更好的了。@kaya3,这是一种将二进制编码为十六进制值的方法,所以是的,这是一种更好的存储数据的方法。查看我的新的最后一段。基于你的上一段ph,我怀疑您不理解UTF-8和十六进制之间的区别。工作量较小:
binary=“00000000”。子字符串(binary.length())+binary;
while((enter = in.read()) != -1) {
    String binary = Integer.toBinaryString(enter);
    // left-pad to length 8
    binary = ("00000000" + binary).substring(binary.length());
    code += binary;
}