340 likes | 463 Views
File Input & Output. Sections 10.1-10.3. Outcomes. Understand when to use System.out / System.err Use a Scanner to read from a file add “throws” annotations to methods use the hasNext family of methods to read every element in a file Use a PrintWriter object to write to a file
E N D
File Input & Output Sections 10.1-10.3
Outcomes • Understand when to use System.out / System.err • Use a Scanner to read from a file • add “throws” annotations to methods • use the hasNext family of methods to read every element in a file • Use a PrintWriter object to write to a file • Know when and why to close file streams • Know the difference between files, file names, and file streams
System.in (kbd) System.out Input & Output Streams • System.in and System.out are streams • carry information from one place to another • System.in: from keyboard to program • System.out: from program to monitor keyboard Program monitor
Redirected I/O • Run a program from the command line • Can redirect input & output • read from fileIn.txt • write to fileOut.txt C:\> java MyProg C:\> java MyProg <fileIn.txt >fileOut.txt
System.in (kbd) System.out fileIn.txt myprog.exe fileOut.txt Redirected I/O • Can redirect input & output • read from fileIn.txt • write to fileOut.txt C:\> java MyProg <fileIn.txt >fileOut.txt
Error Output • Sometimes want to write to screen – even if output is being redirected to a file • typically error messages • For that we have System.err • Used just like System.out System.err.print(“Illegal input: Program ” + “terminating.\n\n”);
System.out.println(“Hi!”); System.err.println(“Bye!); System.out System.err Redirection.java fileOut.txt System.err vs. System.out C:\> java Redirection >fileOut.txt Hi! Bye! monitor
Interactive vs Non-Interactive I/O • System.in/out are normally interactive i/o • input comes from user (keyboard) • output goes to user (monitor) • interaction between user and program • Redirection gives non-interactive i/o • input comes from a file • (non-error) output goes to a file
fin (Scanner) fout (PrintWriter) fileIn.txt myprog.exe fileOut.txt File I/O • Can get program to read from/write to files • use a file Scanner instead of kbd/System.in • use a file PrintWriter instead of System.out C:\> java MyFileProg
Why Use Files? • Permanence • can re-use input; don’t need to copy output • can use output of one program as input to next • Accuracy • correct before the program gets it • even “invisible” output characters stored • Ease of use • large quantities of input hard to type correctly
Redirected vs. File I/O • Redirected I/O replaces keyboard/monitor with files • program designed for user interaction • May want to design for file I/O from start • input files need no prompts • output files can have simpler structure • can combine input from/output to multiple files • But still use the familiar commands
Using Files • Need to import some classes import java.util.Scanner; import java.io.PrintWriter; import java.io.File; import java.io.FileNotFoundException; • File I/O like console I/O, except: • file streams need to be declared • file streams need to be opened before use • file streams should be closed when done • there are pesky “exceptions” to deal with
Declaring File Streams • Create a file stream ScannerinStream; input file stream(*) PrintWriteroutStream; output file stream(*) • Typical names for file stream variables in, fin, inStream, inFile out, fout, outStream, outFile • also names that suggest the file contents stuNumFile, encodedFile, …
(*) File Streams • There are actually classes called InputFileStream and OutputFileStream • these are the very basic file streams • they’re not very useful (for us) • Also lots of other kinds of file streams • useful for different kinds of tasks • Scanners and PrintWriters are more useful for the kinds of things we want to do
Using File Streams • Our input streams are Scanner objects int n = fileIn.nextInt(); String line = fileIn.nextLine(); • fileIn acts just like kbd • Our output streams are PrintWriter objects fileOut.println(“The number you entered was ” + n); fileOut.print(“The line was: ‘” + line + “’\n”); • fileOut acts very much like System.out Actually, System.out is a PrintStream, not a PrintWriter. PrintWriters are “new and improved” PrintStreams.
Opening a File for Input • Create a Scanner to read data from the file Scanner fin = new Scanner(new File(“input.txt”)); • need to say that Scanner fin uses a file • our usual Scanner uses System.in Scanner kbd = new Scanner(System.in); • you can do it in two steps File inputFile = new File(“input.txt”); Scanner fin = new Scanner(inputFile); • but why bother? NOTE: new File(“input.txt”) does not mean that input.txt is a new file! We’re just creating a new object to represent that file.
Problem • An error message when we try to open a file • “… java.io.FileNotFoundExceptionmust be caught or declared to be thrown” • We will declare it • later we’ll talk about “catching” it public static void main(String[] args) throws FileNotFoundException { • NOTE where it is – before the body’s opening brace • remember to import the exception class
When to Use a throws Clause • Use throws FileNotFoundException in • any method that does file i/o • input or output • any method that calls any method that has a throws FileNotFoundException clause public static void doFileIO()throws FileNotFoundException{ ... } public static void main(String[] a)throws FileNotFoundException { doFileIO(); } • later we’ll learn how to avoid this annoyance
Example (Part 1) import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; public class Read3NumbersFromFile { public static void main(String[] args) throws FileNotFoundException { int n1, n2, n3; Scanner fin = new Scanner(new File(“3Nums.txt”)); Continued next slide…
Example (Part 2) n1 = fin.nextInt(); n2 = fin.nextInt(); n3 = fin.nextInt(); System.out.println(“The numbers in the file are: ” + n1 + “, ” + n2 + “, and ” + n3); } } • no fin.nextLine(). Why not? • file creator didn’t have to press the enter key!
Names of Objects • Name of the file itself: 3Nums.txt • the file has the numbers in it • Name of the Scanner: fin • the Scanner is “attached” to the file • gets input from the file instead of from the user • Don’t get them confused: int n1 = 3Nums.txt.nextInt(); • errors: illegal name/unknown name
Exercise • Modify the previous program to read four numbers and print their sum • 3Nums.txt actually has four numbers in it. • Last value is a sentinel (see next slide)
Reading a Whole File • Suppose list of numbers is in a file • How shall we read the whole list? • ask user how many numbers in file? • have file start with many numbers it has? • end file with “sentinel” value? • But even better: • we can ask the Scanner • it can check to see if there are more numbers!
Ask the Scanner • Can ask Scanner if file has more data • hasNextInt(), hasNextDouble(), … fin = new Scanner(new File(“3Nums.txt”)); double sum = 0.0; while(fin.hasNextDouble()) { sum += fin.nextDouble(); } System.out.println(“The sum of the #s in the file is ” + sum);
The hasNext Family • There’s a “hasNext” for each “next” • hasNextDouble nextDouble • is the next thing a double read a double • hasNextInt nextInt • is the next thing an int read an int • hasNext next • hasNextLine nextLine • hasNext... just checks if it’s there • you have to use next... to read it
Exercise • Write a program fragment to • open “MyEssay.txt” for input • count the number of words in it • report the number of words to the user
File Output • Just like file input, except: • use PrintWriter instead of Scanner • imported from java.io, not java.util • use print & println instead of next, nextInt, &c. • just like System.out import java.io.PrintWriter; PrintWriterfout = new PrintWriter(new File(“t.txt”)); fout.println(“...”); // print to t.txt
Exercise • Modify the number summing program to send the output to the file Summary.txt
Problem • We open the file for output • We write the sum to the file • But when we look at the file, it’s empty! • Why? Buffering! • takes a long time to find the place to print, but then the printing itself is (relatively) fast • PrintWriter saves up output till it has lots • But if the program ends before it prints it out….
Closing Streams • Need to tell the PrintWriter when you’re done printing stuff to the file • so it knows to send what’s remaining to the file fout.close(); • You should also close Scanners when you’re done with them • frees up the file and system resources fin.close();
Output Files Start Empty • Output files get created if they didn’t already exist • If an output file did already exist, its contents get erased • once you open it (don’t need to print to it) • If you want to add to the old file PrintWriterfout = new PrintWriter(new FileOutputStream(“out.txt”, true));
Reading File Names • Can mix file and user i/o • e.g. ask user for the name of the file Scanner kbd = new Scanner(System.in); System.out.print(“Enter name of file: ”); String fileName = kbd.nextLine(); Scanner fin = new Scanner(new File(fileName)); int n1 = fin.nextInt(); • Reads file name from user • Reads int value from the named file
Exercise • Revise the summing program to read the name of the file the numbers are in • use 3Nums.txt, 100Nums.txt, 1000Nums.txt • use a file that doesn’t exist. What happens? • Revise it again to ask for the output file • use a file that doesn’t already exist • use a file that does already exist • what happens?