import java.io.*; import java.net.URISyntaxException; import java.net.URL; /** * Provide a range of file-handling operations on an AddressBook. * These methods demonstrate a range of basic features of the * java.io package. * * @author David J. Barnes and Michael Kölling. * @version 2011.07.31 */ public class AddressBookFileHandler { // The address book on which i/o operations are performed. private AddressBook book; // The name of a file used to store search results. private static final String RESULTS_FILE = "results.txt"; /** * Constructor for objects of class FileHandler. * @param book The address book to use. */ public AddressBookFileHandler(AddressBook book) { this.book = book; } /** * Save the results of an address-book search to * the file "results.txt" in the project folder. * @param keyPrefix The key prefix to search on. */ public void saveSearchResults(String keyPrefix) throws IOException { File resultsFile = makeAbsoluteFilename(RESULTS_FILE); ContactDetails[] results = book.search(keyPrefix); FileWriter writer = new FileWriter(resultsFile); for(ContactDetails details : results) { writer.write(details.toString()); writer.write('\n'); writer.write('\n'); } writer.close(); } /** * Show the results from the most-recent call to * saveSearchResults. As output is to the console, any * problems are reported directly by this method. */ public void showSearchResults() { BufferedReader reader = null; try { File resultsFile = makeAbsoluteFilename(RESULTS_FILE); reader = new BufferedReader(new FileReader(resultsFile)); System.out.println("Results ..."); String line; line = reader.readLine(); while(line != null) { System.out.println(line); line = reader.readLine(); } System.out.println(); } catch(FileNotFoundException e) { System.out.println("Unable to find the file: " + RESULTS_FILE); } catch(IOException e) { System.out.println("Error encountered reading the file: " + RESULTS_FILE); } finally { if(reader != null) { // Catch any exception, but nothing can be done // about it. try { reader.close(); } catch(IOException e) { System.out.println("Error on closing: " + RESULTS_FILE); } } } } /** * Add further entries to the address book, from a text file. * The file is assumed to contain one element per line, * plus a blank line, for each entry: * name \n phone \n address \n \n * A line may be blank if that part of the details is missing. * @param filename The text file containing the details. * @throws IOException On input failure. */ public void addEntriesFromFile(String filename) throws IOException { // Make sure the file can be found. URL resource = getClass().getResource(filename); if(resource == null) { throw new FileNotFoundException(filename); } filename = resource.getFile(); BufferedReader reader = new BufferedReader( new FileReader(filename)); String name; name = reader.readLine(); while(name != null) { String phone = reader.readLine(); String address = reader.readLine(); // Discard the separating blank line. reader.readLine(); book.addDetails(new ContactDetails(name, phone, address)); name = reader.readLine(); } reader.close(); } /** * Read the binary version of an address book from the given file. * If the file name is not an absolute path, then it is assumed * to be relative to the current project folder. * @param sourceFile The file from where the details are to be read. * @return The address book object. * @throws IOException If the reading process fails for any reason. */ public AddressBook readFromFile(String sourceFile) throws IOException, ClassNotFoundException { // Make sure the file can be found. URL resource = getClass().getResource(sourceFile); if(resource == null) { throw new FileNotFoundException(sourceFile); } try { File source = new File(resource.toURI()); ObjectInputStream is = new ObjectInputStream( new FileInputStream(source)); AddressBook savedBook = (AddressBook) is.readObject(); is.close(); return savedBook; } catch(URISyntaxException e) { throw new IOException("Unable to make a valid filename for " + sourceFile); } } /** * Save a binary version of the address book to the given file. * If the file name is not an absolute path, then it is assumed * to be relative to the current project folder. * @param destinationFile The file where the details are to be saved. * @throws IOException If the saving process fails for any reason. */ public void saveToFile(String destinationFile) throws IOException { File destination = makeAbsoluteFilename(destinationFile); ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream(destination)); os.writeObject(book); os.close(); } /** * Create an absolute file from the given file name. * If the filename is an absolute one already, then use it * unchanged, otherwise assume it is relative to the * current project folder. * @throws IOException If a valid filename cannot be made. */ private File makeAbsoluteFilename(String filename) throws IOException { try { File file = new File(filename); if(!file.isAbsolute()) { file = new File(getProjectFolder(), filename); } return file; } catch(URISyntaxException e) { throw new IOException("Unable to make a valid filename for " + filename); } } /** * Try to determine the name of the current project folder. * This process involves locating the path of the .class file * for this class, and then extracting the name of the folder * containing it. * @throws URISyntaxException If the URL is not formatted correctly. * @return The current project folder. */ private File getProjectFolder() throws URISyntaxException { String myClassFile = getClass().getName() + ".class"; URL url = getClass().getResource(myClassFile); return new File(url.toURI()).getParentFile(); } }