程式扎記: [ Java7 Tutorials ] File I/O (Featuring NIO.2) - Path Operations

標籤

2015年7月16日 星期四

[ Java7 Tutorials ] File I/O (Featuring NIO.2) - Path Operations

Source From Here 
Preface 
The Path class includes various methods that can be used to obtain information about the path, access elements of the path, convert the path to other forms, or extract portions of a path. There are also methods for matching the path string and methods for removing redundancies in a path. This lesson addresses these Pathmethods, sometimes called syntactic operations, because they operate on the path itself and don't access the file system. 

This section covers the following: 
Creating a Path
Retrieving Information About a Path
Removing Redundancies from a Path
Converting a Path
Joining Two Paths
Creating a Path Between Two Paths
Comparing Two Paths

Creating a Path 
Path instance contains the information used to specify the location of a file or directory. At the time it is defined, a Path is provided with a series of one or more names. A root element or a file name might be included, but neither are required. A Path might consist of just a single directory or file name. 

You can easily create a Path object by using one of the following get methods from the Paths (note the plural) helper class: 
  1. Path p1 = Paths.get("/tmp/foo");  
  2. Path p2 = Paths.get(args[0]);  
  3. Path p3 = Paths.get(URI.create("file:///Users/joe/FileTest.java"));  
The Paths.get method is shorthand for the following code: 
  1. Path p4 = FileSystems.getDefault().getPath("/users/sally");  
The following example creates /u/joe/logs/foo.log assuming your home directory is /u/joe, or C:\joe\logs\foo.log if you are on Windows. 
  1. Path p5 = Paths.get(System.getProperty("user.home"),"logs""foo.log");  
Retrieving Information about a Path 
You can think of the Path as storing these name elements as a sequence. The highest element in the directory structure would be located at index 0. The lowest element in the directory structure would be located at index [n-1], where n is the number of name elements in the Path. Methods are available for retrieving individual elements or a subsequence of the Path using these indexes. 

The examples in this lesson use the following directory structure. 
 
Sample Directory Structure 

The following code snippet defines a Path instance and then invokes several methods to obtain information about the path: (Below is written in groovy code
  1. #!/root/groovy/bin/groovy  
  2. import java.nio.file.Path  
  3. import java.nio.file.Paths  
  4.   
  5. def os = System.getProperty("os.name").toLowerCase()  
  6. printf("OS=%s\n", os)  
  7.   
  8. Path path=null  
  9. if('win' in os)  
  10. {  
  11.     // Microsoft Windows syntax  
  12.     path = Paths.get("C:\\home\\joe\\foo");  
  13. }  
  14. else if('solar' in os)  
  15. {  
  16.     // Solaris syntax  
  17.     path = Paths.get("/home/joe/foo");  
  18. }  
  19. else  
  20. {  
  21.     // Linux like  
  22.     path = Paths.get("/home/joe/foo");  
  23. }  
  24.   
  25.   
  26. System.out.format("toString: %s%n", path.toString());  
  27. System.out.format("getFileName: %s%n", path.getFileName());  
  28. System.out.format("getName(0): %s%n", path.getName(0));  
  29. System.out.format("getNameCount: %d%n", path.getNameCount());  
  30. System.out.format("subpath(0,2): %s%n", path.subpath(0,2));  
  31. System.out.format("getParent: %s%n", path.getParent());  
  32. System.out.format("getRoot: %s%n", path.getRoot());  
Here is the output for both Windows and the Solaris OS: 


The previous example shows the output for an absolute path. In the following example, a relative path is specified: 
  1. if('win' in os)  
  2. {  
  3.     // Microsoft Windows syntax  
  4.     path = Paths.get("sally\\bar");  
  5. }  
  6. else if('solar' in os)  
  7. {  
  8.     // Solaris syntax  
  9.     path = Paths.get("sally/bar");  
  10. }  
  11. else  
  12. {  
  13.     // Linux like  
  14.     path = Paths.get("sally/bar");  
  15. }  
Here is the output for Windows and the Solaris OS: 
 

Removing Redundancies From a Path 
Many file systems use "." notation to denote the current directory and ".." to denote the parent directory. You might have a situation where a Path contains redundant directory information. Perhaps a server is configured to save its log files in the "/dir/logs/." directory, and you want to delete the trailing "/." notation from the path. The following examples both include redundancies: 
/home/./joe/foo
/home/sally/../joe/foo

The normalize method removes any redundant elements, which includes any "." or "directory/.." occurrences. Both of the preceding examples normalize to/home/joe/fooIt is important to note that normalize doesn't check at the file system when it cleans up a path. It is a purely syntactic operation. In the second example, if sally were a symbolic link, removing sally/.. might result in a Path that no longer locates the intended file. 

To clean up a path while ensuring that the result locates the correct file, you can use the toRealPath method. 

Converting a Path 
You can use three methods to convert the Path. If you need to convert the path to a string that can be opened from a browser, you can use toUri. For example: 
  1. Path p1 = Paths.get("/home/logfile");  
  2. // Result is file:///home/logfile  
  3. System.out.format("%s%n", p1.toUri());  
The toAbsolutePath method converts a path to an absolute path. If the passed-in path is already absolute, it returns the same Path object. The toAbsolutePathmethod can be very helpful when processing user-entered file names. For example: 
  1. public class FileTest {  
  2.     public static void main(String[] args) {  
  3.   
  4.         if (args.length < 1) {  
  5.             System.out.println("usage: FileTest file");  
  6.             System.exit(-1);  
  7.         }  
  8.   
  9.         // Converts the input string to a Path object.  
  10.         Path inputPath = Paths.get(args[0]);  
  11.   
  12.         // Converts the input Path  
  13.         // to an absolute path.  
  14.         // Generally, this means prepending  
  15.         // the current working  
  16.         // directory.  If this example  
  17.         // were called like this:  
  18.         //     java FileTest foo  
  19.         // the getRoot and getParent methods  
  20.         // would return null  
  21.         // on the original "inputPath"  
  22.         // instance.  Invoking getRoot and  
  23.         // getParent on the "fullPath"  
  24.         // instance returns expected values.  
  25.         Path fullPath = inputPath.toAbsolutePath();  
  26.     }  
  27. }  
The toAbsolutePath method converts the user input and returns a Path that returns useful values when queried. The file does not need to exist for this method to work. The toRealPath method returns the real path of an existing file and performs several operations in one: 
* If LinkOption.NOFOLLOW_LINKS is passed to this method and the file system supports symbolic links, this method resolves any symbolic links in the path.
* If the Path is relative, it returns an absolute path.
* If the Path contains any redundant elements, it returns a path with those elements removed.

This method throws an exception if the file does not exist or cannot be accessed. For example: 
  1. try {  
  2.     Path fp = path.toRealPath();  
  3. catch (NoSuchFileException x) {  
  4.     System.err.format("%s: no such" + " file or directory%n", path);  
  5.     // Logic for case when file doesn't exist.  
  6. catch (IOException x) {  
  7.     System.err.format("%s%n", x);  
  8.     // Logic for other sort of file error.  
  9. }  
Joining Two Paths 
You can combine paths by using the resolve method. You pass in a partial path , which is a path that does not include a root element, and that partial path is appended to the original path. For example, consider the following code snippet: 
  1. // Solaris  
  2. Path p1 = Paths.get("/home/joe/foo");  
  3. // Result is /home/joe/foo/bar  
  4. System.out.format("%s%n", p1.resolve("bar"));  
Or 
  1. // Microsoft Windows  
  2. Path p1 = Paths.get("C:\\home\\joe\\foo");  
  3. // Result is C:\home\joe\foo\bar  
  4. System.out.format("%s%n", p1.resolve("bar"));  
Passing an absolute path to the resolve method returns the passed-in path: 
  1. // Result is /home/joe  
  2. Paths.get("foo").resolve("/home/joe");  
Creating a Path Between Two Paths 
A common requirement when you are writing file I/O code is the capability to construct a path from one location in the file system to another location. You can meet this using the relativize method. This method constructs a path originating from the original path and ending at the location specified by the passed-in path. The new path is relative to the original path. 

For example, consider two relative paths defined as joe and sally
  1. Path p1 = Paths.get("joe");  
  2. Path p2 = Paths.get("sally");  
In the absence of any other information, it is assumed that joe and sally are siblings, meaning nodes that reside at the same level in the tree structure. To navigate from joe to sally, you would expect to first navigate one level up to the parent node and then down to sally
  1. // Result is ../sally  
  2. Path p1_to_p2 = p1.relativize(p2);  
  3. // Result is ../joe  
  4. Path p2_to_p1 = p2.relativize(p1);  
Consider a slightly more complicated example: 
  1. Path p1 = Paths.get("home");  
  2. Path p3 = Paths.get("home/sally/bar");  
  3. // Result is sally/bar  
  4. Path p1_to_p3 = p1.relativize(p3);  
  5. // Result is ../..  
  6. Path p3_to_p1 = p3.relativize(p1);  
A relative path cannot be constructed if only one of the paths includes a root element. If both paths include a root element, the capability to construct a relative path is system dependent. The recursive Copy example uses the relativize and resolve methods. 

Comparing Two Paths 
The Path class supports equals, enabling you to test two paths for equality. The startsWith and endsWith methods enable you to test whether a path begins or ends with a particular string. These methods are easy to use. For example: 
  1. Path path = ...;  
  2. Path otherPath = ...;  
  3. Path beginning = Paths.get("/home");  
  4. Path ending = Paths.get("foo");  
  5.   
  6. if (path.equals(otherPath)) {  
  7.     // equality logic here  
  8. else if (path.startsWith(beginning)) {  
  9.     // path begins with "/home"  
  10. else if (path.endsWith(ending)) {  
  11.     // path ends with "foo"  
  12. }  
The Path class implements the Iterable interface. The iterator method returns an object that enables you to iterate over the name elements in the path. The first element returned is that closest to the root in the directory tree. The following code snippet iterates over a path, printing each name element: 
  1. Path path = ...;  
  2. for (Path name: path) {  
  3.     System.out.println(name);  
  4. }  
The Path class also implements the Comparable interface. You can compare Path objects by using compareTo which is useful for sorting. 

You can also put Path objects into a Collection. See the Collections trail for more information about this powerful feature. 

When you want to verify that two Path objects locate the same file, you can use the isSameFile method, as described in Checking Whether Two Paths Locate the Same File

Supplement 
Java 獲取當前操作系統的信息

2 則留言:

  1. 連結錯誤?
    Java 獲取當前操作系統的信息
    localhost/jforum/posts/list/2266.page

    回覆刪除
    回覆
    1. Thanks for the reminding, the link has been updated:
      http://puremonkey2010.blogspot.com/2012/09/java-java.html

      刪除

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!