2016-05a-FilesAndFoldersx

Download Report

Transcript 2016-05a-FilesAndFoldersx

File Input & Output
Sections 10.1-10.3
Outcomes
 Know the difference between files and streams
 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 how to read an entire text file
 including files of numbers (!)
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
System.in
(kbd)
keyboard
System.out
Program
monitor
File Streams
 Can get program to read from/write to files
 connect Scanner to a file instead of System.in
 use a PrintWriter instead of System.out
 carry information to/from files
fin
(Scanner)
fileIn.txt
fout
(PrintWriter)
myprog.exe
fileOut.txt
Streams and Files
File exists as a whole, on the disk (or key)
Stream just connects it to the program
 data comes in/goes out in pieces
3Numbers.txt
Input File
Read3NumbersFromFile.class
fin
fout
Scanner
PrintWriter
Program
SumOf3.txt
Output File
Streams and Files




File exists in secondary memory
File has a name
Data is in the file
Scanner carries the data
3Numbers.txt
Read3NumbersFromFile.class
(Possible) Program Variables




A String variable for the file name
A File variable for the file
A Scanner variable for the Scanner
Variable(s) for the data
3Numbers.txt
“3Numbers.txt”
Read3NumbersFromFile.class
Text Files
 We will only read from text files
 have .txt extension on a Windows system
» tho’ Windows may hide it from you!
 Text files can contain numbers (numerals)
 and may contain only numbers
10 15
340 -7
-2 103
3Numbers.txt
Twas
brillig
and the
slithy
toves
poem.txt
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
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
Scanner inStream;
PrintWriter outStream;
input file stream(*)
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 String object for the file’s name
String fileName = “3Numbers.txt”;
 Create a File object to represent the file
File dataFile = new File(fileName);
 Create a Scanner to read data from the file
Scanner fin = new Scanner(dataFile);
 Or combine it all into one command
Scanner fin = new Scanner(new File(“3Numbers.txt”));
NOTE: new File(…) does not mean that the file is new!
We’re just creating a new object to represent that file.
Problem
 An error message when we try to open a file
 “… java.io.FileNotFoundException
must 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 opens a file
» 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)
Javadoc @throws Tag
 Add @throws tag to javadoc comment
 says that this method throws an exception
 says what kind(s) of exception it throws
 says why it might be thrown
/**
*…
* @throws FileNotFoundException if 3Nums.txt cannot be found
*/
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”
 nextDouble  hasNextDouble
» will nextDouble work?
 nextInt  hasNextInt
» will nextInt work?
 next  hasNext
 nextLine  hasNextLine
 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;
PrintWriter fout = 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
PrintWriter fout = 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?
Read and Save a File’s Data
 When reading from a file, you often don’t
know how many elements there will be
 use an ArrayList to store the data
 Loop until file ends, adding elements
while (fin.hasNext()) {
myWords.add(fin.next());
}
 reads all the words of that file into myWords
 don’t need to check for filled array
Reading All Numbers from a File
 Loop until no more numbers
 remember to use wrapper class
ArrayList<Double> myNumbers = new ArrayList<Double>();
Scanner fin = new Scanner(new File(fileName));
while (fin.hasNextDouble()) {
myNumbers.add(fin.nextDouble());
}
fin.close();
» (still need to catch/declare FileNotFoundException)
Exercise
 Revise this code to read integer values
instead of doubles
ArrayList<Double> myNumbers = new ArrayList<Double>();
Scanner fin = new Scanner(new File(fileName));
while (fin.hasNextDouble()) {
myNumbers.add(fin.nextDouble());
}
fin.close();
Questions?
 Next time:




how do we catch FileNotFoundExceptions?
why would we?
what other kinds of exceptions can we catch?
what the heck is an exception, anyway?
Files & Folders
 Files exist inside folders
src
Lab03
J:
NetBeans Projects
Lab05
myProg.java
classes
myProg.class
Lab05Data.txt
 J:\ NetBeans Projects\Lab03\src\myProg.java
 J:\ NetBeans Projects\Lab05\Lab05Data.txt
Files & Folders
 If you just give the name of the file…
 myData.txt
 …then looks in the project folder
 not the src folder!
 But you can specify other folders
 absolute/relative paths
File Paths
 Somewhat system dependent
 but can always use / to separate folder names
 remember to “escape” \ if inside quote marks
 Absolute path
 J:/JCreator LE/Lab05/Lab05Data.txt
 Relative path (from L03 folder)
 ../Lab05/Lab05Data.txt
File Paths
 Use / in Strings in your code
 will work on any machine, not just Windows
 “..” means the folder my folder is in
 “../..” means the folder that it’s in
» and so on!
 Put data files in project folder
 Try to use relative paths
The File Class
 Why do we write “new File(…)”?
 it’s not always a new file, after all!
 Creating a File object
 a program object to represent the file
 (remember, the Scanner/PrintWriter is for
communicating with the file)
 actually just holds the name of the file, but…
 …it knows it’s supposed to be the name of a file
Yet Another Variable
 You can create a variable for the File
File f = new File(fileName);
 You can ask the File object about the file





does this file exist?
can we read from it?
can we write to it?
is it a folder/directory?
and more
f.exists()
f.canRead()
f.canWrite()
f.isDirectory()
these methods may throw SecurityExceptions, but they
don’t need to be checked (they are RunTime Exceptions)
Getting a Readable File
 Keep asking for file names until we get one
that says it’s readable
String fileName;
File f;
do {
System.out.print(“Enter a readable file name: ”);
fileName = kbd.nextLine();
f = new File(fileName);
} while (!f.canRead());
But Still Need to Catch…
 Knowing that a file is readable/writable
doesn’t mean you can skip the try/catch
 file could get deleted between the time you ask
if it’s readable and the time you try to create the
Scanner/PrintWriter!