When reading and writing text files :
Example 2 This example demonstrates using Scanner to read a file line by line (it does not perform a write operation) :
- it is almost always a good idea to use buffering (default size is 8K)
- it is often possible to use references to abstract base classes, instead of references to specific concrete classes
- there is always a need to pay attention to exceptions (in particular, IOException and FileNotFoundException)
- always needs to be called, or else resources will leak
- will automatically flush the stream, if necessary
- calling close on a "wrapper" stream will automatically call close on its underlying stream
- closing a stream a second time has no consequence
- BufferedReader - readLine
- BufferedWriter - write + newLine
- Scanner - allows reading files in a compact way (example)
FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader in = new InputStreamReader(fis, "UTF-8");
FileOutputStream fos = new FileOutputStream("test.txt");
OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8");
Scanner scanner = new Scanner(file, "UTF-8");
Example 1
This example uses JDK 1.5. To make it compatible with JDK 1.4, just change StringBuilder to StringBuffer:- import java.io.*;
- public class ReadWriteTextFile {
- /**
- * Fetch the entire contents of a text file, and return it in a String.
- * This style of implementation does not throw Exceptions to the caller.
- *
- * @param aFile is a file which already exists and can be read.
- */
- static public String getContents(File aFile) {
- //...checks on aFile are elided
- StringBuilder contents = new StringBuilder();
- try {
- //use buffering, reading one line at a time
- //FileReader always assumes default encoding is OK!
- BufferedReader input = new BufferedReader(new FileReader(aFile));
- try {
- String line = null; //not declared within while loop
- /*
- * readLine is a bit quirky :
- * it returns the content of a line MINUS the newline.
- * it returns null only for the END of the stream.
- * it returns an empty String if two newlines appear in a row.
- */
- while (( line = input.readLine()) != null){
- contents.append(line);
- contents.append(System.getProperty("line.separator"));
- }
- }
- finally {
- input.close();
- }
- }
- catch (IOException ex){
- ex.printStackTrace();
- }
- return contents.toString();
- }
- /**
- * Change the contents of text file in its entirety, overwriting any
- * existing text.
- *
- * This style of implementation throws all exceptions to the caller.
- *
- * @param aFile is an existing file which can be written to.
- * @throws IllegalArgumentException if param does not comply.
- * @throws FileNotFoundException if the file does not exist.
- * @throws IOException if problem encountered during write.
- */
- static public void setContents(File aFile, String aContents)
- throws FileNotFoundException, IOException {
- if (aFile == null) {
- throw new IllegalArgumentException("File should not be null.");
- }
- if (!aFile.exists()) {
- throw new FileNotFoundException ("File does not exist: " + aFile);
- }
- if (!aFile.isFile()) {
- throw new IllegalArgumentException("Should not be a directory: " + aFile);
- }
- if (!aFile.canWrite()) {
- throw new IllegalArgumentException("File cannot be written: " + aFile);
- }
- //use buffering
- Writer output = new BufferedWriter(new FileWriter(aFile));
- try {
- //FileWriter always assumes default encoding is OK!
- output.write( aContents );
- }
- finally {
- output.close();
- }
- }
- /** Simple test harness. */
- public static void main (String... aArguments) throws IOException {
- File testFile = new File("C://Temp//blah.txt");
- System.out.println("Original file contents: " + getContents(testFile));
- setContents(testFile, "The content of this file has been overwritten...");
- System.out.println("New file contents: " + getContents(testFile));
- }
- }
- import java.io.*;
- import java.util.Scanner;
- public final class ReadWithScanner {
- public static void main(String... aArgs) throws FileNotFoundException {
- ReadWithScanner parser = new ReadWithScanner("C://Temp//test.txt");
- parser.processLineByLine();
- log("Done.");
- }
- /**
- * @param aFileName full name of an existing, readable file.
- */
- public ReadWithScanner(String aFileName){
- fFile = new File(aFileName);
- }
- /** Template method that calls {@link #processLine(String)}. */
- public final void processLineByLine() throws FileNotFoundException {
- Scanner scanner = new Scanner(fFile);
- try {
- //first use a Scanner to get each line
- while ( scanner.hasNextLine() ){
- processLine( scanner.nextLine() );
- }
- }
- finally {
- //ensure the underlying stream is always closed
- scanner.close();
- }
- }
- /**
- * Overridable method for processing lines in different ways.
- *
- * <P>This simple default implementation expects simple name-value pairs, separated by an
- * '=' sign. Examples of valid input :
- * <tt>height = 167cm</tt>
- * <tt>mass = 65kg</tt>
- * <tt>disposition = "grumpy"</tt>
- * <tt>this is the name = this is the value</tt>
- */
- protected void processLine(String aLine){
- //use a second Scanner to parse the content of each line
- Scanner scanner = new Scanner(aLine);
- scanner.useDelimiter("=");
- if ( scanner.hasNext() ){
- String name = scanner.next();
- String value = scanner.next();
- log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim()) );
- }
- else {
- log("Empty or invalid line. Unable to process.");
- }
- //(no need for finally here, since String is source)
- scanner.close();
- }
- // PRIVATE //
- private final File fFile;
- private static void log(Object aObject){
- System.out.println(String.valueOf(aObject));
- }
- private String quote(String aText){
- String QUOTE = "'";
- return QUOTE + aText + QUOTE;
- }
- }