Java中的位操作与输出
如果您有二进制字符串(字面上的字符串对象只包含1和0),如何将它们作为位输出到文件中Java中的位操作与输出,java,bit-manipulation,Java,Bit Manipulation,如果您有二进制字符串(字面上的字符串对象只包含1和0),如何将它们作为位输出到文件中 这是一个文本压缩机,我正在工作;它仍然困扰着我,如果能最终让它工作起来那就太好了。谢谢 最简单的方法是简单地获取8个连续字符,将它们转换为一个字节并输出该字节。如果可以识别流的结尾,请在结尾处填充零,或者在文件开头添加长度(以位为单位)的头 内部循环看起来像: 字节[]缓冲区=新字节[(string.length+7)/8]; 对于(int i=0;i=0;--j) if(字符串[i*8+j]=='1') 当
这是一个文本压缩机,我正在工作;它仍然困扰着我,如果能最终让它工作起来那就太好了。谢谢 最简单的方法是简单地获取8个连续字符,将它们转换为一个字节并输出该字节。如果可以识别流的结尾,请在结尾处填充零,或者在文件开头添加长度(以位为单位)的头 内部循环看起来像:
字节[]缓冲区=新字节[(string.length+7)/8];
对于(int i=0;i=0;--j)
if(字符串[i*8+j]=='1')
当前|=1假设字符串有8位的倍数(否则可以填充),利用Integer.valueOf方法中的Java内置解析来执行以下操作:
String s = "11001010001010101110101001001110";
byte[] data = new byte[s.length() / 8];
for (int i = 0; i < data.length; i++) {
data[i] = (byte) Integer.parseInt(s.substring(i * 8, (i + 1) * 8), 2);
}
String s=“1100101000010101110101001001110”;
字节[]数据=新字节[s.length()/8];
对于(int i=0;i
然后,您应该能够非常简单地将字节写入FileOutputStream
另一方面,如果你寻找效率,你应该考虑不使用一个字符串来开始存储这些比特,但是直接在你的压缩器中建立字节。
如果你幸运,java. Math.BigType可以为你做任何事情。
public class BitOutputStream extends FilterOutputStream
{
private int buffer = 0;
private int bitCount = 0;
public BitOutputStream(OutputStream out)
{
super(out);
}
public void writeBits(int value, int numBits) throws IOException
{
while(numBits>0)
{
numBits--;
int mix = ((value&1)<<bitCount++);
buffer|=mix;
value>>=1;
if(bitCount==8)
align8();
}
}
@Override
public void close() throws IOException
{
align8(); /* Flush any remaining partial bytes */
super.close();
}
public void align8() throws IOException
{
if(bitCount > 0)
{
bitCount=0;
write(buffer);
buffer=0;
}
}
}
String s = "11001010001010101110101001001110";
byte[] bytes = (new java.math.BigInteger(s, 2)).toByteArray();
这取决于字节顺序(大端)和右对齐(如果位数不是8的倍数)这是您想要的,但以后修改数组可能比自己进行字符转换更简单。我很好奇——0和1是如何以字符串形式结束的,而不是以字节数组或其他更合适的数据类型结束的?这是因为我递归地将“0”和“1”字符从我的Huffman TreeThis添加到Stringbuffer中的olution使用字符数组而不是字符串对象,但它很容易修改。我认为Java字符有2个字节宽?如果前导字节是UTF8前缀字符,它们可以是。这有什么关系?从字符串中提取字符并与其他字符进行比较,而不进行任何转换或解码。构造函数bigineger(字符串)接受一个以10为基数的参数。它应该是新的BigInteger(s,2)危险!此解决方案永远不会在输出字节数组中产生前导零,即使它们属于。BigInteger会更好。如果他将位存储在文件中,它可能大于32。BigInteger将无法正确处理前导零,并且此方法在超过32位的情况下工作正常。它在一个类型中解析8。顺便说一句,如果s
由于在分配字节数组时使用整数除法,因此少于8个字符。这就是为什么答案以“假设字符串具有8位的倍数”开头的原因。
if (nextChar == '0')
{
bos.writeBits(0, 1);
}
else
{
bos.writeBits(1, 1);
}
String s = "11001010001010101110101001001110";
byte[] bytes = (new java.math.BigInteger(s, 2)).toByteArray();