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.
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.
Recall:
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(); System.out.println(readIn);
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(); System.out.println(readIn);
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(); fileChooser.showSaveDialog(this); 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. bw.close(); //FORGETTING THIS IS A VER COMMON ERROR
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.)
234 private void saveAsMenuItemMouseReleased(java.awt.event.MouseEvent evt) { 235 236 try { 237 238 JFileChooser jfc = new JFileChooser(); 239 jfc.showSaveDialog(this); 240 BufferedWriter bw; 241 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(); 249 250 } catch (Exception e) { 251 System.out.println("Error within saving."); 252 } 253 254 } 255 256 private void openMenuItemMouseReleased(java.awt.event.MouseEvent evt) { 257 258 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(); 265 266 StringTokenizer st = new StringTokenizer(readIn, ":"); 267 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 } 273 274 } catch (Exception e) { 275 System.out.println("Error in opening."); 276 } 277 }