, , , :
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class BitOutputStream extends FilterOutputStream {
private int bits = 0;
private int n = 0;
private long totalBits = 0;
public BitOutputStream(OutputStream out) {
super(out);
}
private void writeSingleBit(int bit) throws IOException {
bits = (bits << 1) | (bit & 1);
n++;
totalBits++;
if (n == 8) {
super.write(bits);
bits = 0;
n = 0;
}
}
public void writeBits(int bitsToWrite, int numberOfBits) throws IOException {
for (int i = numberOfBits - 1; i >= 0; i--) {
int bit = bitsToWrite >> i;
writeSingleBit(bit);
}
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
for (int i = 0; i < len; i++)
writeBits(b[off + i], 8);
}
@Override
public final void write(int b) throws IOException {
writeBits(b, 8);
}
@Override
public final void flush() throws IOException {
writeBits(0, (8 - n) & 0x07);
}
public long getTotalBits() {
return totalBits;
}
}
unit test:
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.junit.Test;
public class BitOutputStreamTest {
@Test
public void hello() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitOutputStream bos = new BitOutputStream(baos);
bos.writeBits(0x00, 2);
bos.writeBits(0x01, 2);
bos.writeBits(0x02, 2);
bos.writeBits(0x02, 2);
bos.writeBits(0x03, 2);
assertEquals(10, bos.getTotalBits());
bos.close();
assertEquals(16, bos.getTotalBits());
assertArrayEquals(new byte[] { 0x1A, (byte) 0xC0 }, baos.toByteArray());
}
}
, , , .
(2010-09-25): write(byte[], int, int). off .