如何将一定数量的位写入不是 8 的倍数的文件
How to write an amount of bits to a file that is not multiple of 8
我正在编写一个 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 个数字?
将位编码为字节数组的最简单方法是通过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;
}
我正在编写一个 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 个数字?
将位编码为字节数组的最简单方法是通过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;
}