Lab 17: Writing bits and bytes to a file
You are to write a writer class that writes a file in bits.
Writing out bits
Create the following class BitWriter. The class should have one constructor:
- BitWriter(OutputStream outStream)
Sets the data stream that you will write to outStream. For example, to open a file
for writing, you can use the following in the interactions pane or in a method that uses your BitWriter:
File outFile = new File(filename)
if (!outFile.exists()) { // so you do not accidentally overwrite your files!
BitWriter writer = new BitWriter(new FileOutputStream(outFile));
You can not directly write a bit at a time to a file. The smallest unit you can write is a byte
using the write() method of OutputStream. What you will need to do is maintain a
1 byte buffer and an index into the buffer. The index keeps track of the next bit to write to the buffer.
When the buffer is full, you write the buffer to the OutputStream and then clear the buffer and
reset the index. On close, you will may likely have a partially filled buffer. In that case,
fill the unset bits with 0 (if they are not already 0) and then write the buffer.
Now add the following methods. The descriptions below assume that the BitReader reads each byte from the left
to the right. If your reader reads in the other direction, you should do the same in the methods below.
- void writeBits(String bits) throws IOException
Writes a sequence of bits represented by the String bits.
The method should work as follows. You should start with a byte buffer initialized to 0 and an index set at 7.
For each element of the string bits:
- If the element is a 1, set the buffer's bit at the index to 1.
- Decrement the index.
- If the index is now less than 0, write the bit using the output stream's write method, set the buffer to 0,
and set the index to 7.
- void writeByte(byte value) throws IOException
Writes value as the next 8 bits written.
You should let i run from 7 to 0, and for the ith bit of value, send either a "1"
or a "0" to the above method. Alternatively, you could build the whole string first, and then send it.
- void writeInt(int value) throws IOException
Writes value as the next 32 bits written.
For i going from 3 to 0, write the ith byte of value using the above method.
- void close() throws IOException
Writes out anything still buffered before closing the OutputStream and then closes the OutputStream.
Optional improvement
It is actually very inefficient to write one byte at a time to a file. It is much faster to write out a
large chunk at a time. You can do this by creating a second buffer that is an array of bytes.
I suggest using a large power of 2, such as 1024, 2048, 4096 (1K, 2K, 4K), bytes for the buffer. That will
better match the page size of the computers memory. Then you use the write(byte[] b) method
of OutputStream to
write out the entire array at a time. Then the 1 byte buffer will write to the array, and when the array is full,
you will write the whole array to OutputStream in one step and then reset it. On close
you will need to write the byte buffer to the array, and then write the array to the OutputStream.
In this case, you only want to write part of the array (the part that was filled) and so use the third
write method of OutputStream.
At the end of the lab, email what you have to your instructor, hsc@albion.edu.