如何将一定量的位写入不是8的倍数的文件

时间:2018-03-06 15:13:49

标签: java arrays byte bit binary-data

我正在编写一个用哈夫曼树压缩文本的java应用程序 我得到的结果是一个1和0的数组。现在它是byte[]

只有我想在一个字节中写入8个1和0,因为其他"01"将占用的内容是字符"e"的两倍。

现在我一直在使用

byte[] output = loadedTree.encode(text);

try(ByteOutputStream boas = new ByteOutputStream()) {
    boas.write(output);
    boas.writeTo(new FileOutputStream(basePath + name));
} catch (IOException e) {
    e.printStackTrace();
}

output数组中,每个元素都是(byte) 1(byte) 0

如果我有这样的数据,如何将此数据写入文件,例如7或9个数字?

1 个答案:

答案 0 :(得分:2)

将位编码为字节数组的最简单方法是通过BitSet

private static byte[] bitsToBytes(byte[] bits) {
  BitSet bitSet = new BitSet();
  for (int i = 0; i < bits.length; i++) {
    bitSet.set(i, bits[i] == 1);
  }
  return bitSet.toByteArray();
}

注意bits[i] == 1而不仅仅是bits[i],因为它将是一个接受两个索引的不同方法,而不是索引和值。 以下是检查方法:

public static void main(String[] args) {
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{0})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1, 1})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1, 0, 1})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1, 1, 1, 1, 1, 1, 1})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1, 1, 1, 1, 1, 1, 1, 0})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1, 1, 1, 1, 1, 1, 1, 1})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{0, 0, 1, 1, 0, 0, 0, 0})));
  System.out.println(Arrays.toString(bitsToBytes(new byte[]{1, 1, 1, 1, 1, 1, 1, 1,
                                                            0, 0, 1, 1, 0, 0, 0, 0})));
}

反向转换(如注释中所要求的)通常需要位数,以忽略尾随的零位。这是代码:

private static byte[] bytesToBits(int nbits, byte[] bits) {
  BitSet bitSet = BitSet.valueOf(bits);
  byte[] result = new byte[nbits];
  for (int i = 0; i < result.length; i++) {
    result[i] = (byte) (bitSet.get(i) ? 1 : 0);
  }
  return result;
}