Showing posts with label INPUT. Show all posts
Showing posts with label INPUT. Show all posts

Friday, 21 September 2012

A Java CSV File Reader

One of the most common types of data file is a CSV (Comma Separated Value) file. They can be exported by many popular applications, notable spreadsheet programs like Excel and Numbers. They are easy to read into your Java programs once you know how.

Reading the file is as simple as reading a text file. The file has to be opened, a BufferedReader object is created to read the data in a line at a time.

Once a line of data has been read, we make sure that it's not null, or empty. If it is, we've hit the end of the file and there's no more data to read. If it isn't, we then use the split() method that's a member of Java's String object. This will split a string into an array of Strings using a delimiter that we give it.

The delimiter for a CSV file is a comma, of course. Once we've split() the string, we have all the element in an Array from which our Java programs can use the data. For this example, I just use a for loop to print out the data, but I could just as well sort on the values of one of the cells, or whatever I need to do with it in my program.

The Steps

  1. Open the file with a BufferedReader object to read it a line at a time.

  2. Check to see if we've got actual data to make sure we haven't finished the file.

  3. Split the line we read into an Array of String using String.split()

  4. Use our data.


The Program
// CSVRead.java
//Reads a Comma Separated Value file and prints its contents.

import java.io.*;
import java.util.Arrays;

public class CSVRead{

 public static void main(String[] arg) throws Exception {

  BufferedReader CSVFile = 
        new BufferedReader(new FileReader("Example.csv"));

  String dataRow = CSVFile.readLine(); // Read first line.
  // The while checks to see if the data is null. If 
  // it is, we've hit the end of the file. If not, 
  // process the data.

  while (dataRow != null){
   String[] dataArray = dataRow.split(",");
   for (String item:dataArray) { 
      System.out.print(item + "\t"); 
   }
   System.out.println(); // Print the data line.
   dataRow = CSVFile.readLine(); // Read next line of data.
  }
  // Close the file once all data has been read.
  CSVFile.close();

  // End the printout with a blank line.
  System.out.println();

 } //main()
} // CSVRead


Downloads

This program, and an example CSV file to use it with (a section of a spreadsheed I use to keep track of my integrated circuits) are available at my code archive.

Writing to CSV Files with Java

Writing to a CSV file is as simple as writing a text file. In this case, we write a comma between each field, and a newline at the end of each record.

Give it a try, starting with TextSave.java, modify it appropriately, then see what your favorite spreadsheet program thinks of the results.

Saturday, 15 September 2012

Java File Save and File Load: Objects

Jump to Reading Data from Files with Java>>


Saving Data to Files with Java


Saving objects to a file in Java has a few steps to it, but it's pretty easy. We open a file to write to, create a "stream" for putting objects into the file, write the objects to that stream to put them in the file, then close the stream and file when we're done.

To reiterate:

1. Open a file.

2. Open an object stream to the file.

3. Write the objects to that stream.

4. Close the stream and file.

1. Opening the File
To open a file for writing, we use a FileOutputStream object. When we construct the new FileOutputStream, we give it a file name to open. If the file name exists, it opens the existing file. Otherwise, it creates a new file. To keep things simple, we're not going to check for a file existing here, or anything like that.

Example:

FileOutputStream saveFile = new FileOutputStream("saveFile.sav");

2. Open an Object Stream
To write objects to the FileOutputStream, we create an ObjectOutputStream. We give it the FileOutputStream object we've set up when we construct the new ObjectOutputStream object.

Example:

ObjectOutputStream save = ObjectOutputStream(saveFile);

3. Write Objects
When we write objects to the ObjectOutputStream, they are sent out through it to the FileOutputStream and into the file.

Example:

save.writeObject(objectToSave);

4. Close Up
When we close the ObjectOutputStream, it'll also close our FileOutputStream for us, so this is just one step.

Example:

save.close();

Example Program:
import java.io.*;
import java.util.ArrayList;

public class SaveObjects{

  public static void main(String[] arg){

    // Create some data objects for us to save.
    boolean powerSwitch=true;
    int x=9, y=150, z= 675;
    String name="Galormadron", setting="on", plant="rutabaga";
    ArrayList stuff = new ArrayList();
    stuff.add("One");
    stuff.add("Two");
    stuff.add("Three");
    stuff.add("Four");
    stuff.add("Five");

    try{  // Catch errors in I/O if necessary.
      // Open a file to write to, named SavedObjects.sav.
      FileOutputStream saveFile=new FileOutputStream("SaveObj.sav");

      // Create an ObjectOutputStream to put objects into save file.
      ObjectOutputStream save = new ObjectOutputStream(saveFile);

      // Now we do the save.
      save.writeObject(powerSwitch);
      save.writeObject(x);
      save.writeObject(y);
      save.writeObject(z);
      save.writeObject(name);
      save.writeObject(setting);
      save.writeObject(plant);
      save.writeObject(stuff);

      // Close the file.
      save.close(); // This also closes saveFile.
    }
    catch(Exception exc){
      exc.printStackTrace(); // If there was an error, print the info.
    }
  }
}

Reading Data Files with Java


Now we need to know how to get data back from a file with Java. Since the data objects were stored using an ObjectOutputStream, they are saved in a way that makes them easy to read back using an ObjectInputStream.

There's one problem with ObjectImputStream, however. It doesn't return objects of the specific classes that they were originally. It just returns generic Objects. To get things back into their original class, we have to cast them into that type. Usually that means we need to know what their class was when they were written. It's possible to save class information along with the data, but in this case we just assume that we're reading back a file we have written, so we already know what class everything should be. I'll go into the details of reading other files in another article.

The steps are practically the same as for writing objects to a file:

1. Open a file.

2. Open an object stream from the file.

3. Read the objects to that stream.

4. Close the stream and file.

1. Opening the File
To open a file for reading, we use a FileInputStream object. When we construct the new FileIntputStream, we give it a file name to open. If the file name exists, it opens the existing file. Otherwise, we get an error which will print out a nastygram when we get to our catch statement. To keep things simple, we're not going to check for a file existing here.

Example:

FileInputStream saveFile = new FileInputStream("saveFile.sav");

2. Open an Object Stream
To read objects to the FileInputStream, we create an ObjectInputStream. We give it the FileInputStream object we've set up when we construct the new ObjectInputStream.

Example:

ObjectInputStream restore = ObjectInputStream(saveFile);

3. Read Objects
When we read objects from the ObjectInputStream, it gets then from the file.

Example:

Object obj = restore.readObject();

3 and a half. Cast Back to Class
Step 3. only restores a generic Object. If we know the original class, we should cast the Object back to its original class when we read it. If we had stored a String object, we'd read it something like this:

String name = (String) restore.readObject();

4. Close Up
When we close the ObjectInputStream, it'll also close our FileInputStream for us, so this is just one step.

Example:

restore.close();

Here's an example program to read back information saved by the first example program:
import java.io.*;
import java.util.ArrayList;

public class RestoreObjects{

 public static void main(String[] arg){

  // Create the data objects for us to restore.
  boolean powerSwitch=false;
  int x=0, y=0, z=0;
  String name="", setting="", plant="";
  ArrayList stuff = new ArrayList();
  
  // Wrap all in a try/catch block to trap I/O errors.
  try{
   // Open file to read from, named SavedObjects.sav.
   FileInputStream saveFile = new FileInputStream("SaveObj.sav");

   // Create an ObjectInputStream to get objects from save file.
   ObjectInputStream save = new ObjectInputStream(saveFile);

   // Now we do the restore.
   // readObject() returns a generic Object, we cast those back
   // into their original class type.
   // For primitive types, use the corresponding reference class.
   powerSwitch = (Boolean) save.readObject();
   x = (Integer) save.readObject();
   y = (Integer) save.readObject();
   z = (Integer) save.readObject();
   name = (String) save.readObject();
   setting = (String) save.readObject();
   plant = (String) save.readObject();
   stuff = (ArrayList) save.readObject();

   // Close the file.
   save.close(); // This also closes saveFile.
  }
  catch(Exception exc){
   exc.printStackTrace(); // If there was an error, print the info.
  }

  // Print the values, to see that they've been recovered.
  System.out.println("\nRestored Object Values:\n");
  System.out.println("\tpowerSwitch: " + powerSwitch);
  System.out.println("\tx=" + x + " y=" + y + " z=" + z);
  System.out.println("\tname: " + name);
  System.out.println("\tsetting: " + setting);
  System.out.println("\tplant: " + plant);
  System.out.println("\tContents of stuff: ");
  System.out.println("\t\t" + stuff);
  System.out.println();

  // All done.
 }
}

<<Return to How to Save to a File with Java

The example programs can be downloaded at:
Begin With Java Code Downloads

Friday, 14 September 2012

Getting Keyboard Input for Console Apps: Java's Scanner Class

A nice gift that came with Java 1.5 was the Scanner class. It's part of the java.util package. This class simplifies many common programming tasks. One is getting text from the keyboard.

Prior to Scanner, this took a couple of extra steps. With Scanner, it's a snap. Just as we use System.out to print text to the command line, we use System.in to receive input. Like System.out, System.in is a data stream object. In this case, an InputStream object.
import java.util.Scanner;

public class TrollTalk{
  public static void main(String arg[]){
    String nayme="";  // Declare & initialize a String to hold input.
    Scanner input=new Scanner(System.in); // Decl. & init. a Scanner.

    System.out.print("Whut yur nayme? >");  // Troll asks for name.
    nayme=input.next(); // Get what the user types.
    System.out.println();  // Move down to a fresh line.
    // Then say something trollish and use their name.
    System.out.println("Hur, hur! Dat's a phunny nayme, " + nayme + "!");
  }
}

Our Scanner is named input. We could have called it gzorgnplat, if we wanted to--there's nothing magic about the name 'input'. We attach that name to a new Scanner object that accepts vlues from System.in. Then we print a message so that the user knows they're supposed to type something. The message is a question we want them to answer and a greater-than sign to let them know the computer is ready for them to type.

Being able to accept input while the program is running lets us create interactive command line apps.

Scanner can also be used to get particular types of input like numbers of particular primitive types.

It can also be used to get information from files in the same way it gets information from the user's keyboard. But that's another lesson.

import Statements

An import statement is a way of making more of the functionality of Java available to your program. Java can do a lot of things, and not every program needs to do everything. So, to cut things down to size, so to speak, Java has its classes divided into "packages." Your own classes are part of packages, too.

No import Needed

The simple Hello.java program we've used as an example so far doesn't have any import statements:

public class Hello{
  public static void main(String arg[]){
    System.out.println("Hello.");
  }
}

Everything in the program is already available to the compiler. The compiler can access any class in the java.lang package without needing an import statement. It can also access any classes in the "local" package, which is any classes defined in files in the same directory as the program being compiled that aren't part of another package (that is, they don't have a package statement at the start of the file.)

import Required

Anything that isn't in the java.lang package or the local package needs to be imported. An example is the Scanner class. If you look up the Scanner class in the Java API Specification, you'll see that it is in the java.util package. Remember, to look it up you scroll to the class name in the lower left frame then click on it to bring up its definition in the main frame of the browser. Class names are in regular typeface, interfaces are in italics (some classes and interfaces have the same name.)

Here's an example program that uses Scanner, with an import statement:

import java.util.Scanner;

public class ScannerTest{
  public static void main(String arg[]){

    // scanner gets its input from the console.
    Scanner scanner = new Scanner(System.in);
    String name = "";

    // Get the user's name.
    System.out.print("Your name, adventurer? >");
    name = scanner.next();
    System.out.println();

    // Print their name in a a message.
    System.out.println("Welcome, " + name + " to  Javaland!");
  }
}

We imported just the class Scanner from java.util in the import statement in this program. If we'd been using multiple classes from java.util, we could have made all the classes in java.util available to us by using this import statement:

import java.util.*;

The * is a "regular expression operator" that will match any combination of characters. Therefore, this import statement will import everything in java.util. If you have tried entering and running the example program above, you can change the import statement to this one.

If we need multiple classes from different packages, we use an import statement for each package from which we need to import classes (or interfaces, or any other part of that package we need.) It's not unusual to see a series of import statements near the start of a program file:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

Now, you may wonder why we have statements importing java.awt.* and java.awt.event.*. It seems like if you import java.awt.* that ought to import everything "under" java.awt, right? And the "dot" notation sure makes it look like java.awt.event is under java.awt.

Package Names and Those Misleading Dots

The thing is, each package with its own name is an entirely separate entity. The dot notation and name similarities are just a convention for making it easier to keep track of which packages have functions that are related to each other. One package isn't inside another one. java.awt.event is an entirely separate package from java.awt, it's not inside java.awt.

This can be very confusing, since the other use of the "dot notation" is a way of getting to something that is "inside" or a member of something else. System.out.println() is a way of getting at the println() method that's a member of out which is a member of the System class. But it doesn't work that way with packages. Each package name is a whole different package, and each package needs its own import statement. java.awt.event is entirely different from java.awt.

You can see package names in the API reference in the upper left frame. If you click on a package name, the lower left frame with change to limit what it shows to just the items in the package you've clicked.