如何在Java中读取/写入文件中的位?

时间:2009-12-03 15:37:07

标签: java file bit-manipulation

我需要将文件流作为位读取,然后我应该能够再次将位写入文件。是否有任何课程用于此目的?

5 个答案:

答案 0 :(得分:6)

据我所知,没有内置的方法直接在位级别进行。有多种方法可以使用内置流逐字节读/写。您可以在流上编写一个包装器,它看起来像是在读取和写入位。

如果你想要已经写好的东西,那就找一些做某种音频或视频编码的开源项目,因为有类似的东西。例如,FLAC编解码器有一个可能满足您需求的BitInputStream。

答案 1 :(得分:5)

我对CERN的colt图书馆非常满意。不记得它是否支持文件I / O但我用它来读取比特流,分析和修改它们并将它们写回文件。

答案 2 :(得分:2)

已移至https://github.com/jinahya/bit-io

请查看http://jinahya.googlecode.com/svn/trunk/com.googlecode.jinahya/bit-io/src/main/java/com/googlecode/jinahya/io/

<dependency>
  <!-- resides in central repo -->
  <groupId>com.googlecode.jinahya</groupId>
  <artifactId>bit-io</artifactId>
  <version>1.0-alpha-13</version>
</dependency>

这是一个小型的便捷库,用于使用Java读取/写入任意长度的位。

final InputStream stream;
final BitInput input = new BitInput(new BitInput.StreamInput(stream));

final int b = input.readBoolean(); // reads a 1-bit boolean value
final int i = input.readUnsignedInt(3); // reads a 3-bit unsigned int
final long l = input.readLong(47); // reads a 47-bit signed long

input.align(1); // 8-bit byte align; padding


final WritableByteChannel channel;
final BitOutput output = new BitOutput(new BitOutput.ChannelOutput(channel));

output.writeBoolean(true); // writes a 1-bit boolean value
output.writeInt(17, 0x00); // writes a 17-bit signed int
output.writeUnsignedLong(54, 0x00L); // writes a 54-bit unsigned long

output.align(4); // 32-bit byte align; discarding

答案 3 :(得分:0)

Preon可能就是你要找的东西。看看你的问题,我可以想象Preon甚至可能比你想要的更多

将Preon视为一个库,它为比特流编码内容提供Hibernate对关系数据库和JAXB到XML的目标。现在,它存在几个模块。其中一个模块是preon-binding。这是实际的数据绑定框架。 (由注释驱动。)

然而,preon-binding是建立在preon-bitbuffer之上的(在后来的版本中重新配音为preon-io)。该库具有BitBuffer类型的抽象,用于访问比特流压缩数据。

alt text http://preon.flotsam.nl/images/layers.png

去年夏天发布的Preon不支持编码。那是在进行中。

答案 4 :(得分:0)

只是为了让您了解如何制作自己的流包装器,这是代码片段。

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class BitInputStream extends FilterInputStream {

    private int bitsBuffer = -1;

    private int remainingBits = 0;

    public BitInputStream(InputStream in) {
        super(in);
    }

    @Override
    public int read() throws IOException {
        if (remainingBits == 0) {
            bitsBuffer = in.read();
            remainingBits = Byte.SIZE;
        }
        if (bitsBuffer == -1) {
            return -1;
        }
        remainingBits--;
        return (bitsBuffer >> remainingBits) & 1;
    }

}

正如您所看到的,如果某个位可用,则重写read()方法返回0或1;如果达到基础流的末尾,则返回-1。

import org.junit.Test;
import java.io.ByteArrayInputStream;
import static org.junit.Assert.assertEquals;

public class BitInputStreamTest {

    @Test
    public void read() throws Exception {
        // 99 in two's complement binary form is 01100011
        BitInputStream in = new BitInputStream(
          new ByteArrayInputStream(new byte[]{99}));

        assertEquals(0, in.read());
        assertEquals(1, in.read());
        assertEquals(1, in.read());
        assertEquals(0, in.read());

        assertEquals(0, in.read());
        assertEquals(0, in.read());
        assertEquals(1, in.read());
        assertEquals(1, in.read());

        assertEquals(-1, in.read());
    }

}