Java中的位操作和输出

时间:2008-09-18 15:54:46

标签: java bit-manipulation

如果你有二进制字符串(字面意思只包含1和0的String对象),你会如何将它们作为位输出到文件中?

这是我正在研究的文本压缩器;它仍然困扰着我,终于让它运转起来真好。谢谢!

4 个答案:

答案 0 :(得分:6)

最简单的是简单地取8个连续的字符,将它们变成一个字节并输出该字节。如果您可以识别流末尾,则在末尾填充零,或者在文件开头添加长度(以位为单位)的标题。

内部循环看起来像:


byte[] buffer = new byte[ ( string.length + 7 ) / 8 ];
for ( int i = 0; i < buffer.length; ++i ) {
   byte current = 0;
   for ( int j = 7; j >= 0; --j )
       if ( string[ i * 8 + j ] == '1' )
           current |= 1 << j;
   output( current );
}

你需要做一些调整,但这是一般的想法。

答案 1 :(得分:6)

如果你很幸运,java.math.BigInteger可能会为你做一切。

String s = "11001010001010101110101001001110";
byte[] bytes = (new java.math.BigInteger(s, 2)).toByteArray();

这取决于字节顺序(big-endian)和右对齐(如果位数不是8的倍数)是你想要的但是之后修改数组可能比执行更简单角色转换自己。

答案 2 :(得分:2)

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;
        }
    }
}

然后......

if (nextChar == '0')
{
    bos.writeBits(0, 1);
}
else
{
    bos.writeBits(1, 1);
}

答案 3 :(得分:1)

假设String有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);
}

然后你应该能够非常简单地将字节写入FileOutputStream

另一方面,如果你在寻找效率,你应该考虑不使用String来存储开头的位,而是直接在压缩器中建立字节。