// Intro to using binary files in Java for input and output. This program will CS1501 -- Fall 2003 // simply copy any file, whether it is text, executable or anything else. // It will then output the 8 leftmost bits and the 8 rightmost bits of an // integer to demonstrate some binary operations. import java.io.*; This is an inserted line import javax.swing.*; //FOR RECITATION: This is an inserted line //Maybe we could print out copies of this original code and distribute them to // Recommend highly that they compile and run this program to see what it does. // the students. (Of course they should have line numbers down the side.) // Emphasize that it demonstrates two separate things, as detailed above. These This is an inserted line // two tasks it demonstrates are unrelated. //At first, I think we should just emphasize that all files are "binary files" // and clarify that a "binary file" is not a text file that you open up in notepad This is a replaced line // read the file byte by byte, the byte you will be reading are the ascii values that This is a replaced line // so each 1 is 8-bits that represent the number 31 in binary, and each 0 is 8 bits that // represent the number 30 in binary. //We may also consider starting off with a quick tutorial on binary numbers // just as a refresher b/c I noticed some blank faces when I started recitation // with the 1's and 0's representing base ten numbers this morning. { public class binaryio public static void main(String [] args) { //I believe if the students use these two object types for //reading from and writing to binary files, they'll be able to //complete the assignment.... FileInputStream infile = null; FileOutputStream outfile = null; //Although DataInputStream and DataOutputStream //are also object types they can use that may be more flexible //and powerful as they have methods that can read //16-bits (readUnsignedShort) and write a byte or a short, etc String ifname = null; // string for name of input file int ch; String ofname = null; // string for name of output file This is an inserted line while (true) { { //get filename from user ifname = JOptionPane.showInputDialog(null, "File name?"); try //give it to the input file stream infile = new FileInputStream(ifname); break; } { } System.out.println("File " + ifname + " could not be opened"); } ofname = ifname + ".cop"; This is a replaced line This is a replaced line This is a replaced line //They can read the input file that they will be compressing (or //decompressing) just like this... ch = infile.read(); // Read ahead because we must test for end of file while (ch != -1) { outfile.write(ch); // <-- This is how they will write the // to a binary file // compressed data (or the freshly decoded data) ch = infile.read(); // get the next byte } infile.close(); outfile.close(); } catch (IOException e1) { System.out.println("Some bogusness with the file"); System.exit(0); } //The tricky thing for them will be processing the byte once they've read it in // and converting it to the encoded bits, then gathering encoded bits one byte // at a time before writing each byte. One student I heard was planning to pull // out each bit and store the bits into integer arrays, then manipulate them as // integers, then write out every 8 bits. // 00001010 (the value here is 10) // you could do the following: // int value = 10; //For example, if you need to write the following sequence of bits: // since the write command writes the 8 least significant bits of any integer, // outfile.write(value); // which is a 32-bit data type. They can look up all the specs for the //If they use this method, they could calculate the base ten value of the bit // sequence, store it in an integer, then use the write command to add it to // the output file. //This next section shows how to extract a certain number of bits from an // integer value. They might need this after they have read in a byte, then // stored it into an integer, and now they want to extract the bits from it. FileOutputStream newFile = null; try { //This output file will hold the extracted bits newFile = new FileOutputStream("wacky.out"); //This is is the value we will be extracting bits from //(It's binary representation is: 2^30 + 2^24 + 2^7 + 2^3 + 2^1) int val = 1090519178; //This is the number of bits we are extracting from the left This is a replaced line int bits = 8; //the bits extracted from the left will be stored This is a replaced line int rightout = 0; //the bits extracted from the right will be stored: //right-shift out 24 bits of the integer value, //leaving the top 8 bits only, now in the bottom eight slots leftout = val >> (32-bits); // should be 01000001 = 65 //left-shift out 24 bits of the integer value, //leaving the bottom 8 bits only, now in the top eight slots, //then right-shift these bottom 8 bits back to the bottom // eight slots rightout = (val << (32 - bits)) >> (32 - bits); //write these two values to the output file. newFile.write(leftout); // should be 10001010 = 138 newFile.write(rightout); newFile.close(); // "A," which corresponds to the ascii code 65, and a strange // symbol, which corresponds to the ascii code 138. //read the values back in from the file we just wrote to. FileInputStream reFile = new FileInputStream("wacky.out"); int lval = reFile.read(); int rval = reFile.read(); reFile.close(); //print out the values 65 and 138 System.out.println("leftmost " + bits + " bits = " + lval); } This is an inserted line System.out.println("rightmost " + bits + " bits = " + rval); This is an inserted line catch (Exception e) System.out.println("Some exception " + e + " has occurred"); { } This is a replaced line