Java NIO之擁抱Path和Files

**Java高級特性加強-NIO

本部分網絡上有大量的資源能夠參考,在這裏作了部分整理並作了部分勘誤,感謝前輩的付出,每節文章末尾有引用列表~html


請戳GitHub原文: github.com/wangzhiwubi…java

大數據成神之路系列:

請戳GitHub原文: github.com/wangzhiwubi…git

Java高級特性加強-集合程序員

Java高級特性加強-多線程github

Java高級特性加強-Synchronized面試

Java高級特性加強-volatileapache

Java高級特性加強-併發集合框架編程

Java高級特性加強-分佈式數組

Java高級特性加強-Zookeepertomcat

Java高級特性加強-JVM

Java高級特性加強-NIO

寫在全部文字的前面:做者在此特別推薦Google排名第一的關於NIO的文章: tutorials.jenkov.com/java-nio/in… 雖然是英文的,可是看下來並不困難。後面若是各位看官呼聲很高,做者會翻譯這一系列文章。

Java NIO之擁抱Path和Files

文件I/O基石:Path

Java7中文件IO發生了很大的變化,專門引入了不少新的類來取代原來的基於java.io.File的文件IO操做方式:

import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;·
......
複製代碼

咱們將從下面幾個方面來學習Path類:

  • 建立一個Path
  • File和Path之間的轉換,File和URI之間的轉換
  • 獲取Path的相關信息
  • 移除Path中的冗餘項

1 建立一個Path 建立Path實例能夠經過 Paths工具類 的 get()方法:

//使用絕對路徑
 Path path= Paths.get("c:\\data\\myfile.txt");
//使用相對路徑
Path path = Paths.get("/home/jakobjenkov/myfile.txt");
複製代碼

下面這種建立方式和上面等效:

Path path = FileSystems.getDefault().getPath("c:\\data\\myfile.txt");
複製代碼

2 File和Path之間的轉換,File和URI之間的轉換

File file = new File("C:/my.ini");
        Path p1 = file.toPath();
        p1.toFile();
        file.toURI();
複製代碼

3 獲取Path的相關信息

//使用Paths工具類的get()方法建立
       Path path = Paths.get("D:\\XMind\\bcl-java.txt");
       System.out.println("文件名:" + path.getFileName());
       System.out.println("名稱元素的數量:" + path.getNameCount());
       System.out.println("父路徑:" + path.getParent());
       System.out.println("根路徑:" + path.getRoot());
       System.out.println("是不是絕對路徑:" + path.isAbsolute());
       //startsWith()方法的參數既能夠是字符串也能夠是Path對象
       System.out.println("是不是覺得給定的路徑D:開始:" + path.startsWith("D:\\") );
       System.out.println("該路徑的字符串形式:" + path.toString());
複製代碼

結果:

文件名:bcl-java.txt
名稱元素的數量:2
父路徑:D:\XMind
根路徑:D:\
是不是絕對路徑:true
是不是覺得給定的路徑D:開始:true
該路徑的字符串形式:D:\XMind\bcl-java.txt
複製代碼

4 移除冗餘項 某些時候在咱們須要處理的Path路徑中可能會有一個或兩個點

  • .表示的是當前目錄
  • ..表示父目錄或者說是上一級目錄:

下面經過實例來演示一下使用Path類的normalize()和toRealPath()方法把.和..去除。

  • normalize() : 返回一個路徑,該路徑是冗餘名稱元素的消除。
  • toRealPath() : 融合了toAbsolutePath()方法和normalize()方法
//.表示的是當前目錄
        Path currentDir = Paths.get(".");
        System.out.println(currentDir.toAbsolutePath());//輸出C:\Users\Administrator\NIODemo\.
        Path currentDir2 = Paths.get(".\\NIODemo.iml");
        System.out.println("原始路徑格式:"+currentDir2.toAbsolutePath());
        System.out.println("執行normalize()方法以後:"+currentDir2.toAbsolutePath().normalize());
        System.out.println("執行toRealPath()方法以後:"+currentDir2.toRealPath());
        //..表示父目錄或者說是上一級目錄:
        Path currentDir3 = Paths.get("..");
        System.out.println("原始路徑格式:"+currentDir3.toAbsolutePath());
        System.out.println("執行normalize()方法以後:"+currentDir3.toAbsolutePath().normalize());
        System.out.println("執行toRealPath()方法以後:"+currentDir3.toRealPath());
複製代碼

結果:

C:\Users\Administrator\NIODemo\.
原始路徑格式:C:\Users\Administrator\NIODemo\.\NIODemo.iml
執行normalize()方法以後:C:\Users\Administrator\NIODemo\NIODemo.iml
執行toRealPath()方法以後:C:\Users\Administrator\NIODemo\NIODemo.iml
原始路徑格式:C:\Users\Administrator\NIODemo\..
執行normalize()方法以後:C:\Users\Administrator
執行toRealPath()方法以後:C:\Users\Administrator
複製代碼

![d6a70ed9337b5e22fa34de22f36236b4](Java NIO之擁抱Path和Files.resources/1E6CACD6-76A0-4D6C-8E05-C1D9353E293A.png)

擁抱Files類

Java NIO中的Files類(java.nio.file.Files)提供了多種操做文件系統中文件的方法。本節教程將覆蓋大部分方法。Files類包含了不少方法,因此若是本文沒有提到的你也能夠直接查詢JavaDoc文檔。 java.nio.file.Files類是和java.nio.file.Path相結合使用的

1 檢查給定的Path在文件系統中是否存在 經過 Files.exists() 檢測文件路徑是否存在:

Path path = Paths.get("D:\\XMind\\bcl-java.txt");
        boolean pathExists =
                Files.exists(path,
                        new LinkOption[]{LinkOption.NOFOLLOW_LINKS});
        System.out.println(pathExists);//true
複製代碼

注意Files.exists()的的第二個參數。它是一個數組,這個參數直接影響到Files.exists()如何肯定一個路徑是否存在。在本例中,這個數組內包含了LinkOptions.NOFOLLOW_LINKS,表示檢測時不包含符號連接文件。

2 建立文件/文件夾

建立文件: 經過 Files.createFile() 建立文件:

Path target2 = Paths.get("C:\\mystuff.txt");
        try {
            if(!Files.exists(target2))
                Files.createFile(target2);
        } catch (IOException e) {
            e.printStackTrace();
        }
複製代碼

建立文件夾:

  • 經過 Files.createDirectory() 建立文件夾
  • 經過 Files.createDirectories() 建立文件夾

Files.createDirectories()會首先建立全部不存在的父目錄來建立目錄,而Files.createDirectory()方法只是建立目錄,若是它的上級目錄不存在就會報錯。好比下面的程序使用Files.createDirectory() 方法建立就會報錯,這是由於個人D盤下沒有data文件夾,加入存在data文件夾的話則沒問題。

Path path = Paths.get("D://data//test");
    try {
        Path newDir = Files.createDirectories(path);
    } catch(FileAlreadyExistsException e){
        // the directory already exists.
    } catch (IOException e) {
        //something else went wrong
        e.printStackTrace();
    }
複製代碼

3 刪除文件或目錄 經過 Files.delete()方法 能夠刪除一個文件或目錄:

Path path = Paths.get("data/subdir/logging-moved.properties");

try {
    Files.delete(path);
} catch (IOException e) {
    //deleting file failed
    e.printStackTrace();
}
複製代碼

4 把一個文件從一個地址複製到另外一個位置 經過Files.copy()方法能夠吧一個文件從一個地址複製到另外一個位置

Path sourcePath = Paths.get("data/logging.properties");
Path destinationPath = Paths.get("data/logging-copy.properties");

try {
    Files.copy(sourcePath, destinationPath);
} catch(FileAlreadyExistsException e) {
    //destination file already exists
} catch (IOException e) {
    //something else went wrong
    e.printStackTrace();
}
複製代碼

copy操做還可能夠強制覆蓋已經存在的目標文件,只須要將上面的copy()方法改成以下格式:

Files.copy(sourcePath, destinationPath,
            StandardCopyOption.REPLACE_EXISTING);
複製代碼

5 獲取文件屬性

Path path = Paths.get("D:\\XMind\\bcl-java.txt");
        System.out.println(Files.getLastModifiedTime(path));
        System.out.println(Files.size(path));
        System.out.println(Files.isSymbolicLink(path));
        System.out.println(Files.isDirectory(path));
        System.out.println(Files.readAttributes(path, "*"));
複製代碼

結果:

2016-05-18T08:01:44Z
18934
false
false
{lastAccessTime=2017-04-12T01:42:21.149351Z, lastModifiedTime=2016-05-18T08:01:44Z, size=18934, creationTime=2017-04-12T01:42:21.149351Z, isSymbolicLink=false, isRegularFile=true, fil
複製代碼

6 遍歷一個文件夾

Path dir = Paths.get("D:\\Java");
        try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){
            for(Path e : stream){
                System.out.println(e.getFileName());
            }
        }catch(IOException e){

        }
複製代碼

結果:

apache-maven-3.5.0
Eclipse
intellij idea
Jar
JDK
MarvenRespository
MyEclipse 2017 CI
Nodejs
RedisDesktopManager
solr-7.2.1
複製代碼

上面是遍歷單個目錄,它不會遍歷整個目錄。遍歷整個目錄須要使用:Files.walkFileTree().Files.walkFileTree()方法具備遞歸遍歷目錄的功能。

7 遍歷整個文件目錄: walkFileTree接受一個Path和FileVisitor做爲參數。Path對象是須要遍歷的目錄,FileVistor則會在每次遍歷中被調用。 FileVisitor須要調用方自行實現,而後做爲參數傳入walkFileTree().FileVisitor的每一個方法會在遍歷過程當中被調用屢次。若是不須要處理每一個方法,那麼能夠繼承它的默認實現類SimpleFileVisitor,它將全部的接口作了空實現。

public class WorkFileTree {
    public static void main(String[] args) throws IOException{
        Path startingDir = Paths.get("D:\\apache-tomcat-9.0.0.M17");
        List<Path> result = new LinkedList<Path>();
        Files.walkFileTree(startingDir, new FindJavaVisitor(result));
        System.out.println("result.size()=" + result.size());
    }

    private static class FindJavaVisitor extends SimpleFileVisitor<Path>{
        private List<Path> result;
        public FindJavaVisitor(List<Path> result){
            this.result = result;
        }
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs){
            if(file.toString().endsWith(".java")){
                result.add(file.getFileName());
            }
            return FileVisitResult.CONTINUE;
        }
    }
}
複製代碼

上面這個例子輸出了個人D:\apache-tomcat-9.0.0.M17也就是個人Tomcat安裝目錄下以.java結尾文件的數量。 結果:

result.size()=4
複製代碼

Files類真的很強大,除了我講的這些操做以外還有其餘不少操做好比:讀取和設置文件權限、更新文件全部者等等操做。

參考文檔:

  • 官方JDK相關文檔
  • 谷歌搜索排名第一的Java NIO教程
  • 《Java程序員修煉之道》
  • 《Java 8編程官方參考教程(第9版)》
  • Java7新特性之文件操做

請戳GitHub原文: https://github.com/wangzhiwubigdata/God-Of-BigData

                   關注公衆號,內推,面試,資源下載,關注更多大數據技術~
                   大數據成神之路~預計更新500+篇文章,已經更新50+篇~ 複製代碼
相關文章
相關標籤/搜索