Home Topic 4

Writing and Reading Data To/From an Unordered Sequential File

We can use the RandomAccessFile to hash things we wish to put to files, and then directly place them there, and find them efficiently. But we can also simply sequentially add stuff to files.

Sequentially Reading From a File

BufferedWriter and BufferedReader are good classes to work with, and a bit more efficient than FileWriter and FileReader alone. And so since we've already used BufferedReader, let's start with sequentially reading from a file. We have already used BufferedReader when reading from the console. Remember that at the beginning of the course we got our input by typing into the Output window, and pressing Enter.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

In that case, we took in a stream of input from the InputStreamReader class, which, in turn tread stuff from the System in object, i.e. what was typed on they keyboard.

This time, to read from a file, the parameter for BufferedReader will be a FileReader object. Our BufferedReader object's readLine() method will read in the entire file.

We can either hardcode in the file path and name, or have the user type it in a textField, or we can use the Save/Save As menus.

Hardcoding the Path And Name

        BufferedReader br = new BufferedReader(new FileReader("/user/Administrator/Public/Classes/File 1");
        String readIn = br.readLine();
        System.out.println(readIn);  //This will print out the entire file.

Getting the (Path and) FileName From a GUI TextField

(And one other difference in the following example is we'll separate the initialization of the FileReader and BufferedReader. The above is more familiar since it is the same one line way as when we first used BufferedReader, but the following is also a valid, and arguable more clear way of doing it.)

        FileReader fr = new FileReader(fileNameInputTF.getText());
        BufferedReader br = new BufferedReader(fr);
        String readIn = br.readLine();

And do note that if you don't type or hardcode in a path name, it is then assumed that the file in question is in the same directory as the application, or Netbeans project in our case.

Getting the Path and FileName via a JFileChooser Object

        JFileChooser jfc = new javax.swing.JFileChooser();
        jfc.showOpenDialog(this);   //Shows the Open dialogue box.
        FileReader fr = new FileReader(jfc.getSelectedFile());   //Whatever path and file the user selects via the dialogue box is sent to the FileReader object.
        BufferedReader br = new BufferedReader(fr);
        String readIn = br.readLine();

Sequentially Writing to a File

The easiest way to write to a file is to put the data in an array, and then do the writing all at once. Here's an example using the JFileChooser way:

        JFileChooser fileChooser = new JFileChooser();
        FileWriter fw = new FileWriter(fileChooser.getSelectedFile());
        BufferedWriter bw = new BufferedWriter(fw);
        String stringToWrite = "";
        for (int i = 0; i < sArray.length; i++) {
           stringToWrite = stringToWrite +sArray[i] + ":";
        bw.write(stringToWrite); //Writing to the hard drive is slow, so by adding the stringToWrite in the above lopo (in RAM) we only write once.

You'll note that we use a class called BufferedWriter, which takes in an instance of a class called FileWriter. The names of these two classes, along with the name of the write() method are as expected. But do also note the BufferedWriter method close() which has to be used after finishing your writing operations. In fact, basically, it is the close() method which "flushes" the buffer, and actually writes the file to the hard drive; the write() simply adds to the buffer, kept in RAM, thereby limiting the number of times that the computer has to go through the slow process of moving data from the RAM to the hard drive - this, in fact is the whole idea of buffering.

(One cute analogy for buffering is when you are unpacking groceries and putting them away. You don't open the refrigerator every time you have something to put there, because you don't want all of the cold air escape from the fridge, so you "buffer" the things to go in the fridge on the kitchen counter, and then when you've got enough there to warrant opening the fridge and loading things in, you do - at that time, you "flush the buffer", and "write" your items to the fridge.)


Another Full Example, Using a Table:

234 private void saveAsMenuItemMouseReleased(java.awt.event.MouseEvent evt) {                                             
236         try {
238             JFileChooser jfc = new JFileChooser();
239             jfc.showSaveDialog(this);
240             BufferedWriter bw;
242             bw = new BufferedWriter(new FileWriter(jfc.getSelectedFile()));
242             String stringToWrite = "";
243             for (int row = 0; row < jTable1.getRowCount(); row++) {
244                 for (int col = 0; col < jTable1.getColumnCount(); col++) {
245                     stringToWrite = stringToWrite + jTable1.getValueAt(row, col) + ":";
246                 }
247             }
247             bw.write(stringToWrite);
248             bw.close();
250         } catch (Exception e) {
251             System.out.println("Error within saving.");
252         }
254     }                                            
256     private void openMenuItemMouseReleased(java.awt.event.MouseEvent evt) {                                           
259         try {
260             JFileChooser jfc = new JFileChooser();
261             jfc.showOpenDialog(this);
262             FileReader fr = new FileReader(jfc.getSelectedFile());
263             BufferedReader br = new BufferedReader(fr);
264             String readIn = br.readLine();
266             StringTokenizer st = new StringTokenizer(readIn, ":");
268             for (int row = 0; row < jTable2.getRowCount(); row++) {
269                 for (int col = 0; col < jTable2.getColumnCount(); col++) {
270                     jTable2.setValueAt(st.nextElement(), row, col);
271                 }
272             }
274         } catch (Exception e) {
275             System.out.println("Error in opening.");
276         }
277     }