In my previous article, I have introduced all of the new functionalities, features and APIs, which are shipped with Java SE 7 release, and here we will see how to migrate or re-write your old IO to new NIO.2 code.
In my daily projects I am developing, I am depending extensively on I/O usage for exchanging files among my systems for integration, and there are a lot of boilerplate code, validations, exceptions checking and security related issues. Therefor I have decided to refactor my code especially critical one to Java SE 7 NIO.2 APIs.
In this article, I will show you a quick guide on how to refactor and map your legacy IO (Input/Output) code, which is prior to Java SE 7 ( java.io.File class was the only mechanism used for file I/O), to the new java.nio.file APIs which comes with rich and tremendous functionalities as part of Java SE 7 and above.
The Java 7 file I/O API JSR 203, has been completely re-architected in the Java SE 7 release; and because of that, you cannot swap one method for another method.
To use the rich functionality offered by the java.nio.file package, the easiest solution is to use the File.toPath method. If the previous statement is not sufficient for your needs, you must rewrite your file I/O code.
Before we dive into the mapping of the functionalities from legacy IO to the new one from Java 7 NIO, I have question to ask.
Why should I migrate from old IO to new NIO.2?
If you have developed more than a few applications based on java.io.File, then you should be familiar with not only its methods, but also its methods’ drawbacks.
For example, many of these methods do not throw exceptions when they fail, there is no real support for symbolic links, metadata access is inefficient, file renaming across platforms is inconsistent, and some methods do not scale, enhanced security and so on.
Let us begin the refactoring process:
The first milestone of refactoring java.io.File code may be considered the conversion of File objects into java.nio.file.Path objects through the java.io.File.toPath() method:
After conversion, you can exploit the Path features.
However, while this is the easiest solution, it may not always satisfy your needs.
Sometimes you will need to rewrite your file I/O code and align code to java.nio.file classes, and for this, you can use the one-by-one correspondence between the two APIs.
The following Table shows this correspondence; this table will make your code transition from Java 5 or 6 to Java 7 much easier:
Javadoc Description | java.io.File | java.nio.file |
Class name correspondence | java.io.File | java.nio.file.Path |
Tests this abstract pathname for equality with the given object | File.equals(Object) | Path.equals(Object) |
Compares two abstract pathnames lexicographically | File.compareTo(File) | Path.compareTo(Path) |
Returns the absolute pathname string of this abstract pathname | File.getAbsolutePath() | Path.toAbsolutePath() |
Returns the absolute form of this abstract pathname | File.getAbsoluteFile() | Path.toAbsolutePath() |
Returns the canonical pathname string of this abstract pathname | File.getCanonicalPath() | Path.toRealPath(LinkOption...) Path.normalize() |
Returns the canonical form of this abstract pathname | File.getCanonicalFile() | Path.toRealPath(LinkOption...) Path.normalize() |
Constructs a file: URI that represents this abstract pathname | File.toURI() | Path.toUri() |
Tests whether the file denoted by this abstract pathname is a normal file | File.isFile() | Files.isRegularFile(Path, LinkOption ...) |
Tests whether the file denoted by this abstract pathname is a directory | File.isDirectory() | Files.isDirectory(Path, LinkOption...) |
Tests whether the file named by this abstract pathname is a hidden file | File.isHidden() | Files.isHidden(Path) |
Tests whether the application can read the file denoted by this abstract pathname | File.canRead() | Files.isReadable(Path) |
Tests whether the application can modify the file denoted by this abstract pathname | File.canWrite() | Files.isWritable(Path) |
Tests whether the application can execute the file denoted by this abstract pathname | File.canExecute() | Files.isExecutable(Path) |
Tests whether the file or directory denoted by this abstract pathname exists | File.exists() | Files.exists(Path, LinkOption...) Files.notExists(Path, LinkOption ...) |
Creates the directory named by this abstract pathname | File.mkdir() | Files.createDirectory(Path, FileAttribute<?> ...) |
Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories | File.mkdirs() | Files.createDirectories(Path, FileAttribute<?> ...) |
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist | File.createNewFile() | Files.createFile(Path, FileAttribute<?> ...) |
Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname | File.list() File.listFiles() | Files.newDirectoryStream(Path) |
Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter | File.list(FilenameFilter) File.listFiles(FileFilter) File.listFiles(FilenameFilter) | Files.newDirectoryStream(Path, DirectoryStream.Filter<? super Path>) Files.newDirectoryStream(Path, String) |
The length of the file denoted by this abstract pathname | File.length() | Files.size(Path) |
Deletes the file or directory denoted by this abstract pathname | File.delete() | Files.delete(Path) Files.deleteIfExists(Path) |
Renames the file denoted by this abstract pathname | File.renameTo(File) | Files.move(Path, Path, CopyOption) |
Sets the owner or everybody’s execute permission for this abstract pathname | File.setExecutable(boolean, boolean) | Files.setAttribute(Path, String, Object, LinkOption...) |
Sets the owner or everybody’s read permission for this abstract pathname | File.setReadable(boolean, boolean) | Files.setAttribute(Path, String, Object, LinkOption...) |
Marks the file or directory named by this abstract pathname so that only read operations are allowed | File.setReadOnly() | Files.setAttribute(Path, String, Object, LinkOption...) |
Sets the owner or everybody’s write permission for this abstract pathname | File.setWritable(boolean, boolean) | Files.setAttribute(Path, String, Object, LinkOption...) |
Returns the time that the file denoted by this abstract pathname was last modified | File.lastModified() | Files.getLastModifiedTime(Path path, LinkOption... options) |
Sets the last-modified time of the file or directory named by this abstract pathname | File.setLastModified(long) | Files.setLastModifiedTime(Path, FileTime) |
Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its name | File.createTempFile(String, String) | Files.createTempFile(String prefix, String suffix, FileAttribute<?>... attrs) |
Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name | File.createTempFile(String, String, File) | Files.createTempFile(Path dir, String prefix, String suffix, FileAttribute<?>... attrs) |
Returns the size of the partition named by this abstract pathname | File.getTotalSpace() | FileStore.getTotalSpace() |
Returns the number of unallocated bytes in the partition named by this abstract path name | File.getFreeSpace() | FileStore.getUnallocatedSpace() |
Returns the number of bytes available to this virtual machine on the partition named by this abstract pathname | File.getUsableSpace() | FilesStore.getUsableSpace() |
Lists the available file system roots | File.listRoots() | FileSystem.getRootDirectories() |
Random access file | java.io.RandomAccessFile | java.nio.channels.SeekableByteChannel |
Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates | File.deleteOnExit() | Replaced by the DELETE_ON_CLOSE option |
Combines two paths | new File(parent,"new_file") | parent.resolve("new_file") |
Happy conversion, refactoring, mapping, and migrating IO from earlier JDKs to new JDK7 NIO2 :)
References:
No comments :
Post a Comment