第九節 netty前傳-NIO 補充Path和File

NIO Path

Java NIO.Path接口位於java.nio.file包中,所以Java Path接口的完全限定名稱是java.nio.file.Path。

Java Path實例表示文件系統中的路徑。路徑可以是絕對的或相對的。絕對路徑包含從文件系統根目錄到其指向的文件或目錄的完整路徑。相對路徑包含相對於其他路徑的文件或目錄的路徑。 很多時候,java.nio.file.Path接口類似於java.io.File類,但存在一些細微差別。在許多情況下,甚至可以使用Path接口替換File類的使用。

  1. 創建path實例

Path path = Paths.get("c:\data\myfile.txt"); 上面的Path 爲接口,Paths爲工廠類

當然上面爲決定路徑,也可以創建相對路徑

//相對路徑,第一個參數作爲相對的參考
Path path = Paths.get("d:\\base",
                       "..\\revlet-path");

NIO file

java.nio.file.Files的Files類提供了幾種操作文件的方法

  1. 檢查文件是否存在
//文件路徑
Path path = Paths.get("data/logging.properties");
//注意第二個參數,的含義作爲判斷文件是否存在的判斷依據,此處表示不依賴文件連接
boolean pathExists =
        Files.exists(path,
            new LinkOption[]{ LinkOption.NOFOLLOW_LINKS});
  1. 創建目錄
Path path = Paths.get("data/subdir");
try {
    Path newDir = Files.createDirectory(path);
} catch(FileAlreadyExistsException e){
    // the directory already exists.
} catch (IOException e) {
    //something else went wrong
    e.printStackTrace();
}
  1. 拷貝
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();
}
  1. 移動文件
Path sourcePath      = Paths.get("data/logging-copy.properties");
Path destinationPath = Paths.get("data/subdir/logging-moved.properties");

try {
    Files.move(sourcePath, destinationPath,
            StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
    //moving file failed.
    e.printStackTrace();
}
  1. 刪除文件
Path path = Paths.get("data/subdir/logging-moved.properties");
try {
    Files.delete(path);
} catch (IOException e) {
    //deleting file failed
    e.printStackTrace();
}
  1. 遞歸遍歷目錄樹的功能。

Files.walkFileTree()方法用於遞歸遍歷目錄樹的功能。參數包含Path實例和FileVisitor作爲參數。FileVisitor是一個接口,業務功能需要自己實現

Files.CONTINUE表示文件遍歷應該正常繼續。

TERMINATE表示文件遍歷應立即終止。

SKIP_SIBLINGS意味着文件遍歷應該繼續但不訪問此文件或目錄的任何兄弟。

SKIP_SUBTREE表示文件遍歷應該繼續但不訪問此目錄中的條目。(path, new FileVisitor<Path>() {
//在訪問任何目錄之前調用
  @Override
  public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
    System.out.println("pre visit dir:" + dir);
    return FileVisitResult.CONTINUE;
  }
//在文件遍歷期間訪問的每個文件(不是目錄)都會調用visitFile()方法
  @Override
  public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
    System.out.println("visit file: " + file);
//返回值
//CONTINUE表示文件遍歷應該正常繼續。
//TERMINATE表示文件遍歷應立即終止。
//SKIP_SIBLINGS意味着文件遍歷應該繼續但不訪問此文件或目錄的任何並列文件。
//SKIP_SUBTREE表示文件遍歷應該繼續但不訪問此目錄中的條目。
    return FileVisitResult.CONTINUE;
  }
//訪問文件失敗,則調用visitFileFailed()方法
  @Override
  public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    System.out.println("visit file failed: " + file);
    return FileVisitResult.CONTINUE;
  }
// 訪問目錄後立即調用postVisitDirectory()方法。
  @Override
  public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
    System.out.println("post visit directory: " + dir);
    return FileVisitResult.CONTINUE;
  }
});
  • walkFileTree 的使用例子
/**
*Files.walkFileTree()遞歸查詢文件
*/
Path rootPath = Paths.get("data");
String fileToFind = File.separator + "README.txt";
//SimpleFileVisitor繼承接口FileVisitor,不過已經幫我我們實現了部分功能
try {
  Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      String fileString = file.toAbsolutePath().toString();
      //System.out.println("pathString = " + fileString);

      if(fileString.endsWith(fileToFind)){
        System.out.println("file found at path: " + file.toAbsolutePath());
        return FileVisitResult.TERMINATE;
      }
      return FileVisitResult.CONTINUE;
    }
  });
} catch(IOException e){
    e.printStackTrace();
}

/**
*Files.walkFileTree()也可用於刪除包含其中所有文件和子目錄的目錄。
*Files.delete()方法只會刪除目錄爲空的目錄。 通過瀏覽所有目錄並刪除每個目錄
*中的所有文件(在visitFile()內部,然後刪除目錄本身(在postVisitDirectory()
*內),您可以刪除包含所有子目錄和文件的目錄。 這是一個遞歸目錄刪除示例
*/
Path rootPath = Paths.get("data/to-delete");
try {
  Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      System.out.println("delete file: " + file.toString());
      Files.delete(file);
      return FileVisitResult.CONTINUE;
    }
    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
      Files.delete(dir);
      System.out.println("delete dir: " + dir.toString());
      return FileVisitResult.CONTINUE;
    }
  });
} catch(IOException e){
  e.printStackTrace();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章