We recently wrote about watching a directory using the new APIs introduced as part of Java 7. In this post let me throw some light on another class added to the java.nio package as part of Java 7 update- java.nio.file.Files. Another piece of information related to this is that complete java.nio.file package was added as part of Java 7 release. I am not going to write about all the methods in Files class, instead pick few of the methods and compare how we would perform the same operation pre Java 7 with that of using Files API.
also read:
Copying the contents of one file to another
Here’s how we would do it in before Java 7- using BufferedReader, BufferedWriter.
//Before Java 7 BufferedReader reader = null; BufferedWriter writer = null; try { reader = new BufferedReader( new FileReader("/tmp/nio/file1")); writer = new BufferedWriter( new FileWriter("/tmp/nio/file2_old")); String dataRead = null; while ((dataRead = reader.readLine()) != null) { writer.write(dataRead); writer.newLine(); } } catch (IOException e) { System.out.println("IOException encoutnered"); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { System.out.println("Exception while closing reader"); } } if (writer != null) { try { writer.close(); } catch (IOException e) { System.out.println("Exception while closing the writer."); } } } System.out.println("File created: " + new File("/tmp/nio/file2_old").exists());
All of you should be familiar with the above code. Now lets see how this can be done using the Files API:
//After Java 7 Path source = Paths.get("/tmp/nio/file1"); Path target = Paths.get("/tmp/nio/file2_new"); try { Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { System.out.println("Exception while copying usng new API"); } System.out.println("File created: " + Files.exists(target));
I know you cannot believe your eyes, that’s the power of APIs and no wonder Scala has loads of them. Lets have a look at the new classes used above:
- Path: This is used to represent the location of a file/directory in the file system.
- Paths – This is the factory class to create instances of Path class.
- Files– A new class with lots of helper methods to perform operations on File.
There are overloaded versions of copy method which can take an InputStream and write to a file, read it from a file and write to OutputStream or read and write to a file. The first 2 help us to choose different source and different destination respectively.
We have used the third variant of the copy method. Apart from the source and target destinations, the copy method also accepts some CopyOption which indicate to the copy function whether to replace any existing file among other options which are supported.
Reading all the lines from a file into a List
:
Lets have a look at the pre Java 7 approach
List<String> linesInFile = new ArrayList<String>(); BufferedReader reader2 = null; try{ String lineRead = null; reader2 = new BufferedReader(new FileReader("/tmp/nio/file3")); while ((lineRead = reader2.readLine()) != null){ linesInFile.add(lineRead); } } catch (IOException e) { System.out.println("IO error"); } System.out.println("Lines read using old style: "); for (String s : linesInFile){ System.out.println(s); }
Pretty straight forward using BufferedReader, but too many unwanted/unrelated code statements.
Lets see how this can be done in using Files API:
//In Java 7 Path sourcePath = Paths.get("/tmp/nio/file3"); try { List<String> linesReadNew = Files.readAllLines(sourcePath, Charset.defaultCharset()); System.out.println("Lines read using new style:"); for(String s : linesReadNew){ System.out.println(s); } } catch (IOException e) { System.out.println("IO Error"); }
So much more concise than the other approach. And the code is easy to read as well. In this example we make use of the readAllLines method of the Files class. It takes a Path instance indicating which file to read and then uses BufferedReader to read through the file but all this is being taken care of the API.
These were just 2 instances of how the new API made the code more concise and easy to understand. There are lot many such methods in the Files class which create a wrapper over the mundane, repeated code written using File API.