init
This commit is contained in:
100
p3/BitInputStream.java
Normal file
100
p3/BitInputStream.java
Normal file
@@ -0,0 +1,100 @@
|
||||
// The BitOutputStream and BitInputStream classes provide the ability to
|
||||
// write and read individual bits to a file in a compact form. One major
|
||||
// limitation of this approach is that the resulting file will always have
|
||||
// a number of bits that is a multiple of 8. In effect, whatever bits are
|
||||
// output to the file are padded at the end with 0's to make the total
|
||||
// number of bits a multiple of 8.
|
||||
//
|
||||
// BitInputStream has the following public methods:
|
||||
// public BitInputStream(String file)
|
||||
// opens an input stream with the given file name
|
||||
// public int nextBit()
|
||||
// reads the next bit from input (throws exception if at end of file)
|
||||
// public boolean hasNextBit()
|
||||
// returns true if there's another bit in the input stream to be read
|
||||
// public void close()
|
||||
// closes the input
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BitInputStream {
|
||||
private FileInputStream input;
|
||||
private int currentByte; // current set of bits (buffer)
|
||||
private int nextByte; // next set of bits (buffer)
|
||||
private int numBits; // how many bits from buffer have been used
|
||||
private int remainingAtEnd; // how many bits will be remaining at the end
|
||||
// after we're done
|
||||
|
||||
private static final int BYTE_SIZE = 8; // bits per byte
|
||||
|
||||
// pre : given file name is legal
|
||||
// post: creates a BitInputStream reading input from the file
|
||||
public BitInputStream(String file) {
|
||||
try {
|
||||
this.input = new FileInputStream(file);
|
||||
|
||||
// Read in the number of remaining bits at the end
|
||||
this.remainingAtEnd = this.input.read();
|
||||
|
||||
// Set up the nextByte field.
|
||||
this.nextByte = this.input.read();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex.toString());
|
||||
}
|
||||
|
||||
this.nextByte();
|
||||
}
|
||||
|
||||
public boolean hasNextBit() {
|
||||
boolean atEnd = this.currentByte == -1;
|
||||
boolean onlyRemaining = this.nextByte == -1
|
||||
&& BYTE_SIZE - this.numBits == this.remainingAtEnd;
|
||||
return !atEnd && !onlyRemaining;
|
||||
}
|
||||
|
||||
// post: reads next bit from input
|
||||
// throws NoSuchElementException if there is no bit to return
|
||||
public int nextBit() {
|
||||
// if at eof, throw exception
|
||||
if (!this.hasNextBit()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
int result = this.currentByte % 2;
|
||||
this.currentByte /= 2;
|
||||
this.numBits++;
|
||||
if (this.numBits == BYTE_SIZE) {
|
||||
this.nextByte();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// post: refreshes the internal buffer with the next BYTE_SIZE bits
|
||||
private void nextByte() {
|
||||
this.currentByte = this.nextByte;
|
||||
if (this.currentByte != -1) {
|
||||
try {
|
||||
this.nextByte = this.input.read();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
this.numBits = 0;
|
||||
}
|
||||
|
||||
// post: input is closed
|
||||
public void close() {
|
||||
try {
|
||||
this.input.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// included to ensure that the stream is closed
|
||||
protected void finalize() {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user