Java中的位操作和输出
时间:2020-03-06 14:22:05 来源:igfitidea点击:
如果我们有二进制字符串(字面上仅包含1和0的String对象),我们将如何将它们作为位输出到文件中?
这是我正在使用的文本压缩程序。它仍然困扰着我,最终使它正常工作将是一件很高兴的事情。谢谢!
解决方案
最简单的方法是简单地获取8个连续字符,将它们转换为一个字节并输出该字节。如果我们可以识别流的末尾,则在末尾填充零,或者在文件的开头添加长度(以位为单位)的标头。
内循环看起来像:
另一方面,如果我们想提高效率,则应考虑不使用String来存储开头的位,而是直接在压缩器中建立字节。
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 ); } You'll need to make some adjustments, but that's the general idea. Answer Assuming the String has a multiple of eight bits, (you can pad it otherwise), take advantage of Java's built in parsing in the Integer.valueOf method to do something like this: 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); }
接着...
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; } } }
如果幸运的话,java.math.BigInteger可以为我们做所有事情。
if (nextChar == '0') { bos.writeBits(0, 1); } else { bos.writeBits(1, 1); }
这确实取决于我们想要的字节顺序(big-endian)和右对齐(如果位数不是8的倍数),但是事后修改数组比自己进行字符转换更简单。
代码数量不匹配