Working with the Path Class

這裡的內容節錄自 Pro Java 7 NIO.2 一書,介紹的是 Path 這個類別,它是 NIO.2 中的一個類別,比起傳統上使用 java.io 中的類別會來的方便,整理如下:

  • defining a path & getting info about a path

從以下的程式及輸出,來說明 Path 類別的使用。

 1 package idv.steven.nio2.path;
 2
 3 import java.nio.file.Path;
 4 import java.nio.file.Paths;
 5
 6 public class Normalize {
 7
 8     public static void main(String[] args) {
 9         String filename = "D:/English/./ESL/Business/ESL Podcast 165 - A Practical Joke.mp3";
10         Path path1 = Paths.get(filename).normalize();
11         System.out.println(path1.toString());
12
13         Path path2 = Paths.get(filename);
14         System.out.println(path2.toString());
15
16         System.out.println(System.getProperty("user.home"));
17
18         System.out.println("Root of this path: " + path1.getRoot());
19         System.out.println("Parent: " + path1.getParent());
20
21         System.out.println("Number of name elements in path: " + path1.getNameCount());
22
23         for (int i = 0; i < path1.getNameCount(); i++) {
24             System.out.println("Name element " + i + " is: " + path1.getName(i));
25         }
26
27         System.out.println("Subpath (0,3): " + path1.subpath(0, 3));
28
29         System.out.println("Filename: " + path1.getFileName().toString());
30     }
31 }

輸出結果如下:

D:\English\ESL\Business\ESL Podcast 165 - A Practical Joke.mp3
D:\English\.\ESL\Business\ESL Podcast 165 - A Practical Joke.mp3
C:\Users\Steven
Root of this path: D:Parent: D:\English\ESL\Business
Number of name elements in path: 4
Name element 0 is: English
Name element 1 is: ESL
Name element 2 is: Business
Name element 3 is: ESL Podcast 165 - A Practical Joke.mp3
Subpath (0,3): English\ESL\Business
Filename: ESL Podcast 165 - A Practical Joke.mp3

在 java.io 中提供的類別,對於檔案系統中的檔名處理,都是交由程式開發者透過處理字串的方式來進行,於是可以看到程式中必然會出現許多處理路徑、檔名的 method 或類別,Path 直接提供了這些程式開發者需要的 method,免去了一直重複發明輪子的困擾。接下說明如下:

    1. normailize: 去除"多餘"的部份,什麼是多餘的? 以上面的程式中 path1 和 path 2作比較,path1 有呼叫 normailize,移除了第二行紅色的部份,輸出的結果比較簡節,實際上是指向同一個檔案。
    2. home directory: 使用者的家目錄,如程式第 16 行所示,因為我是在 Windows 7 中測試,輸出結果為 C:\users\Steven,如果是在 linux 中測試,可能就會是 /home/steven。
    3. root directory: 程式第 18 行,取得根目錄,以上面的程式看,當然就是 D:\。
    4. parent directory: 程式第 19 行可以取得上一層的目錄,因此得到 D:\English\ESL\Business。
    5. 分解完整檔名 (full file name): 程式第 21~27 行是說明如何分解完整的檔名,以往的作法可能會用 String[] folder = filename.split("/"); 這樣的方式處理,現在 Path 類別直接提供了這個功能,21 行是傳回總共有幾層的目錄 (包含檔名),23~25 行則將各層輸出到 console。第 27 行的 subpath 是 Path 類別提供的一個 method,讓程式開發者方便取得完整檔名中所需要的部份。
    6. file name: 第 29 行是取得檔名的方法。
  • ignore symbol link
 1 package idv.steven.nio2.path;
 2
 3 import java.io.IOException;
 4 import java.nio.file.LinkOption;
 5 import java.nio.file.Path;
 6 import java.nio.file.Paths;
 7
 8 public class Convert {
 9
10     public static void main(String[] args) throws IOException {
11         //String filename = "C:/Java/jdk1.7.0_67/README.html";
12         String filename = "D:/README.html";
13         Path path = Paths.get(filename).normalize();
14         System.out.println("path: " + path);
15         System.out.println("path: " + path.toAbsolutePath());
16         System.out.println("real path: " + path.toRealPath(LinkOption.NOFOLLOW_LINKS));
17     }
18 }

在 C:/Java/jdk1.7.0_67 目錄下有個 README.html 的檔案,我們在 D:/ 下建立一個捷徑指向那個檔案,然後如下面的程式分別用 toAbsolutePath 及 toRealPath 存取,會發現當用 toRealPath 存取時,會拋出 exception,如下,顯示該捷徑 (在 linux 下則為 symbol link) 不是一個真實的檔案。這個結果可以讓我們在存取某個目錄下所有檔案時,用來忽略目錄中的捷徑。

path: D:\README.html
path: D:\README.html
Exception in thread "main" java.nio.file.NoSuchFileException: D:\README.html
	at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:90)
	at sun.nio.fs.WindowsLinkSupport.getRealPath(WindowsLinkSupport.java:259)
	at sun.nio.fs.WindowsPath.toRealPath(WindowsPath.java:836)
	at sun.nio.fs.WindowsPath.toRealPath(WindowsPath.java:44)
	at idv.steven.nio2.path.Convert.main(Convert.java:16)
  • comparing two paths

有時候,兩個檔案的完整檔名寫法或有不同,但其實指的是同一個檔案,當使用 Path 類別時,可以比較的出來嗎? 看一下程式 …

 1 package idv.steven.nio2.path;
 2
 3 import java.io.IOException;
 4 import java.nio.file.Files;
 5 import java.nio.file.Path;
 6 import java.nio.file.Paths;
 7
 8 public class Compare {
 9
10     public static void main(String[] args) {
11         String filename1 = "D:/English/./ESL/Business/ESL Podcast 165 - A Practical Joke.mp3";
12         String filename2 = "/English/./ESL/Business/ESL Podcast 165 - A Practical Joke.mp3";
13
14         Path path1 = Paths.get(filename1);
15         Path path2 = Paths.get(filename2);
16
17         if (path1.equals(path2)) {
18             System.out.println("equal");
19         }
20         else {
21             System.out.println("not equal");
22         }
23
24         int compare = path1.compareTo(path2);
25         System.out.println(compare);
26
27         try {
28             boolean check = Files.isSameFile(path1, path2);
29             if(check){
30                 System.out.println("The paths locate the same file!"); //true
31             } else {
32                 System.out.println("The paths does not locate the same file!");
33             }
34         }
35         catch (IOException e) {
36             System.out.println(e.getMessage());
37         }
38     }
39 }

上面程式中 filename1 和 filename2 是同一個檔案,我們先用 equals 及 compareTo 來比較,卻都得不到正確結果! 如下:

not equal
-24
The paths locate the same file!

為什麼會是這樣呢? 因為 equals 的比較方式,在 Path 類別中是以  Object.equals 來比較,當然,path1 和 path2 並非相同的兩個物件,就傳回 false。那麼 compareTo 又是怎麼比較的? 它是以字典的順序來比較,只有當兩個檔名的寫法完全相同,才會傳回 0 表示兩個相同,當第一個大於第二個時,傳回正整數,第一個小於第二個時傳回負整數。要注意的是,compareTo 在不同的作業系統中會有不同的反應,例如在 Windows 中,因為 Windows 的檔名是不分大小寫的,所以它在比較時也不分大小寫,在 Linux 中因為檔名有分大小寫,它在比較時就會區分大小寫。程式的第 28 行是正確的比較方法,只有用這個方法才會得到我們真正要的結果!

时间: 2024-11-08 19:27:41

Working with the Path Class的相关文章

Linux下修改环境变量PATH

1.什么是环境变量(PATH) 在Linux中,在执行命令时,系统会按照PATH的设置,去每个PATH定义的路径下搜索执行文件,先搜索到的文件先执行. 我们知道查阅文件属性的指令ls 完整文件名为:/bin/ls(这是绝对路径), 那你会不会觉得很奇怪:"为什么我可以在任何地方执行/bin/ls这个指令呢? " 为什么我在任何目录下输入 ls 就一定可以显示出一些讯息而不会说找不到该 /bin/ls 指令呢? 这是因为环境变量 PATH 的帮助所致呀! 当我们在执行一个指令癿时候,举例

Description Resource Path Location Type The superclass &quot;javax.servlet.http.HttpServlet&quot; was not foun

一段时间没亲自建新项目玩乐,今天建立了一Maven project的时候发现了以下异常,Description Resource Path Location Type The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path index.jsp /easyBuy/src/main/webapp line 1 JSP Problem 经过查找原因,原来是因为忘记设置server

Spring Cloud ZooKeeper集成Feign的坑2,服务调用了一次后第二次调用就变成了500,错误:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.n

错误如下: 2017-09-19 15:05:24.659 INFO 9986 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]56528192: startup date [Tue Sep 19 15:05:24 CST 2017]; root of context hierarchy 2017-09-19 15:05:24.858 INFO 9986 --

Linux下修改.bash_profile 文件改变PATH变量的值

Linux中含有两个重要的文件 /etc/profile和$HOME/.bash_profile 每当系统登陆时都要读取这两个文件,用来初始化系统所用到的变量,其中/etc/profile是超级用户所用,$HOME/.bash_profile是每个用户自己独立的,我们可以修改该文件来设置一些变量. 命令用法如下 $ cd (进入用户登陆目录) $ls –al .bash_profile(.bash_profile为隐藏文件,因此要用ls –a命令查找) $vi .bash_profile(用vi

配置class PATH

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权:凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记. PATH->是用来配置DOS中的快捷命令,里面存储很多路径,从前置方式去搜索 PATHEXT->后缀配置,搜索的时候配合你名字进行搜索 DOS中的临时环境变量(DOS关闭就失效): 1.SET环境变量名称=环境变量内容 2.临时的环境变量配置会把之前的环境变量内容全部覆盖掉,所以以前的PATH内容就丢失了 3.SET PATH=C:\program Fil

使用path监听指定文件系统的变化

在以前的JAVA版本中,如果程序需要检测文件的变化,那么需要开辟一个线程每隔一段时间去遍历一次指定的目录,如果发现此次遍历结果和上次不同,那么就认为文件变动了 ,这样的方式非常繁琐,JAVA 7之后的NIO.2 Path类提供了一个方法来监听指定文件目录内文件的变化状态. 1.获取文件系统的WatchService对 2.使用Path类的方法去注册一个监听,指定监听文件的哪些状态,如新增.修改.删除. package com.nio2; import java.io.IOException;im

Hive报错 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D

报错信息如下 Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D 解决方法: 编辑 hive-site.xml 文件,添加下边的属性 <property> <name>system:java.io.tmpdir<

leetcode 656. Coin Path

Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The integer B denotes that from any place (suppose the index is i) in the array A, you can jump to any one of the place in the array A indexed i+1, i+2,

如何更改系统环境变量PATH

1. 如何更改系统环境变量PATH? 答:如果是永久更改系统环境变量,对所有用户生效,有两种办法:推荐使用第三种. (1)vim /etc/profile  加入 PATH=$PATH:/usr/local/mysql/bin/ (2)vim /etc/bashrc 加入 PATH=$PATH:/usr/local/mysql/bin/ (3)vim /etc/profile.d/path.sh #!/bin/bash export PATH=$PATH:/ usr/local/mysql/bi

POJ3967Ideal Path[反向bfs 层次图]

Ideal Path Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 1754   Accepted: 240 Description New labyrinth attraction is open in New Lostland amusement park. The labyrinth consists of n rooms connected by m passages. Each passage is colo