您的位置:首页 > 编程语言 > Java开发

Java 按位读取写入文件

2016-11-29 15:34 190 查看
在实现Huffman树时,压缩和解压需要从文件中按位读取,即一次只读一个位或者写一个位。

《算法(第四版)》中提供了一种实现方法,StdIn类和StdOut类,豁然开朗。

按位读取

方法:

1. 开辟一个缓冲区
int buffer
,用于储存位,并记录缓冲区中bit数
n


2. 缓冲区不为空时,进行位运算
buffer>>(n-1)
,即为buffer中的最高位,实现读取一个位的操作

例:

buffer(二进制表示)11001010
n8
buffer向右移7个位
buffer >> (8-1)
,即可得到最高位
1


public static boolean readBoolean() {
if (isEmpty()) throw new NoSuchElementException("Reading from empty input stream");
n--;
boolean bit = ((buffer >> n) & 1) == 1;
if (n == 0) fillBuffer();
return bit;
}


其他部分实现

public final class BinaryStdIn {
private static BufferedInputStream in = new BufferedInputStream(System.in);
private static final int EOF = -1;    // end of file

private static int buffer;            // one character buffer
private static int n;                 // number of bits left in buffer

// static initializer
static {
fillBuffer();
}

// don't instantiate
private BinaryStdIn() { }

private static void fillBuffer() {
try {
buffer = in.read();
n = 8;

4000
}
catch (IOException e) {
System.out.println("EOF");
buffer = EOF;
n = -1;
}
}

/**
* Returns true if standard input is empty.
* @return true if and only if standard input is empty
*/
public static boolean isEmpty() {
return buffer == EOF;
}
}


按位写入

按位写入的实现,主要是利用与运算
|
的特性:

1.
0 | n = n


2.
1 | n = 1


与按位读取相同,我们同样要使用一个缓冲区。

假设要写入的位为 bit,则

1. 将buffer左移一位
buffer <<= 1
,空出一位存放bit

2. 如果bit为1,则 buffer = buffer | 1;如果bit为0,则buffer即为写入bit后的缓冲区

例如:

buffer(二进制表示)110110
bit1
buffer <<= 11101100
bit的8位二进制表示00000001
与运算结果1101101
代码实现

private static void writeBit(boolean bit) {
// add bit to buffer
buffer <<= 1;
if (bit) buffer |= 1;
// if buffer is full (8 bits), write out as a single byte
n++;
if (n == 8) clearBuffer();
}


完整实现

public final class BinaryStdOut {
private static BufferedOutputStream out = new BufferedOutputStream(System.out);

private static int buffer;     // 8-bit buffer of bits to write out
private static int n;          // number of bits remaining in buffer

// don't instantiate
private BinaryStdOut() { }

/**
* Write the specified bit to standard output.
*/
private static void writeBit(boolean bit) {
// add bit to buffer
buffer <<= 1;
if (bit) buffer |= 1;

// if buffer is full (8 bits), write out as a single byte
n++;
if (n == 8) clearBuffer();
}

private static void clearBuffer() {
if (n == 0) return;
if (n > 0) buffer <<= (8 - n);
try {
out.write(buffer);
}
catch (IOException e) {
e.printStackTrace();
}
n = 0;
buffer = 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: