日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747



JAVA 之所以能夠霸占編程語言的榜首,其強大、豐富的類庫功不可沒,幾乎所有的編程問題都能在其中找到解決方案。但在早期的版本當中,輸入輸出(I/O)流并不那么令開發者感到愉快:

1)JDK 1.4 之前的 I/O 沒有緩沖區的概念、不支持正則表達式、支持的字符集編碼有限等等;

2)JDK 1.4 的時候引入了非阻塞 I/O,也就是 NIO 1.0,但遍歷目錄很困難,不支持文件系統的非阻塞操作等等。

為了突破這些限制,JDK 1.7 的時候引入了新的 NIO,也就是本篇文章的主角——NIO 2.0。

01、基石:Path

Path 既可以表示一個目錄,也可以表示一個文件,就像 File 那樣——當然了,Path 就是用來取代 File 的。

1)可以通過 Paths.get() 創建一個 Path 對象,此時 Path 并沒有真正在物理磁盤上創建;參數既可以是一個文件名,也可以是一個目錄名;絕對路徑或者相對路徑均可。

2)可以通過 Files.notExists() 確認 Path(目錄或者文件) 是否已經存在。

3)可以通過 Files.createDirectory() 創建目錄,此時目錄已經在物理磁盤上創建成功,可通過資源管理器查看到。

4)可以通過 Files.createFile() 創建文件,此時文件已經在物理磁盤上創建成功,可通過資源管理器查看到。

5)可以通過 toAbsolutePath() 查看 Path 的絕對路徑。

6)可以通過 resolve() 將 Path 連接起來,參數可以是一個新的 Path 對象,也可以是對應的字符串。

具體的代碼如下:

public class Wanger {
 public static void main(String[] args) {
 // 相對路徑
 Path dir = Paths.get("chenmo");
 // 輸出 dir 的絕對路徑
 System.out.println(dir.toAbsolutePath()); // 輸出:D:programjava.gitjava_demochenmo
 if (Files.notExists(dir)) {
 try {
 // 如果目錄不存在,則創建目錄
 Files.createDirectory(dir);
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 }
 // 這時候 chenmo.txt 文件并未創建
 // 通過 resolve 方法把 dir 和 chenmo.txt 鏈接起來
 Path file = dir.resolve("chenmo.txt");
 // 輸出 file 的絕對路徑
 System.out.println(file.toAbsolutePath()); // 輸出:D:programjava.gitjava_demochenmochenmo.txt
 if (Files.notExists(file)) {
 try {
 // 如果文件不存在,則創建文件
 Files.createFile(file);
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
}

如果要將 File 轉換為 Path,可以通過 File 類的 toPath() 方法完成。代碼示例如下:

File file = new File("沉默王二.txt");
Path path = file.toPath();

如果要將 Path 轉換為 File,可以通過 Path 類的 toFile() 方法完成。代碼示例如下:

Path path = Paths.get("沉默王二.txt");
File file = path.toFile();

02、處理目錄

NIO 2.0 新增的 java.nio.file.DirectoryStream<T> 接口可以非常方便地查找目錄中的(符合某種規則的)文件,比如說我們要查找 chenmo 目錄下的 txt 后綴的文件,代碼示例如下:

// 相對路徑
Path dir = Paths.get("chenmo");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.txt")) {
 for (Path entry : stream) {
 System.out.println(entry.getFileName());
 }
} catch (IOException e) {
 e.printStackTrace();
}

1)Files.newDirectoryStream(Path dir, String glob) 會返回一個過濾后的 DirectoryStream( 目錄流,),第一個參數為目錄,第二個參數為 glob 表達式,比如 *.txt 表示所有 txt 后綴的文件。

2)由于 DirectoryStream 繼承了 Closeable 接口,所以它可以配合 try-with-resources 語法寫出更安全的代碼,目錄流會自動調用 close 方法關閉流,釋放與流相關的資源,不需要再通過 finally 進行主動關閉。

3)DirectoryStream 被稱為目錄流,允許方便地使用 for-each 結構來遍歷目錄。

03、處理目錄樹

目錄樹意味著一個目錄里既有文件也有子目錄,也可能都沒有,也可能有其一。NIO 2.0 可以很方便地遍歷一顆目錄樹,并操作符合條件的文件;這其中關鍵的一個方法就是 Files 類的 walkFileTree,其定義如下:

public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
 throws IOException
 {
 return walkFileTree(start,
 EnumSet.noneOf(FileVisitOption.class),
 Integer.MAX_VALUE,
 visitor);
 }

第二個參數 FileVisitor 被稱為文件訪問器接口,它實現起來非常復雜,要實現 5 個方法呢,但幸好 JDK 的設計者提供了一個默認的實現類 SimpleFileVisitor,如果我們只想從目錄樹中找到 txt 后綴的文件,可以這樣做:

// 相對路徑
Path dir = Paths.get("chenmo");
try {
 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
 @Override
 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
 if (file.toString().endsWith(".txt")) {
 System.out.println(file.getFileName());
 }
 return FileVisitResult.CONTINUE;
 }
 });
} catch (IOException e) {
 e.printStackTrace();
}

通過創建匿名內部類來重寫 SimpleFileVisitor 的 visitFile 方法,如果后綴名為 txt 就打印出來。

04、文件的刪除、復制、移動

創建一個文件非常的簡單,之前我們已經體驗過了,那么刪除一個文件也同樣的簡單,代碼示例如下:

Files.delete(file);
Files.deleteIfExists(file);

使用 Files.delete() 刪除文件之前最好使用 Files.exists() 判斷文件是否存在,否則會拋出 NoSuchFileException;Files.deleteIfExists() 則不用。

復制文件也不復雜,代碼示例如下:

Path source = Paths.get("沉默王二.txt");
Path target = Paths.get("沉默王二1.txt");
Files.copy(source, target);

移動文件和復制文件非常相似,代碼示例如下:

Path source = Paths.get("沉默王二.txt");
Path target = Paths.get("沉默王二1.txt");
Files.move(source, target);

05、快速地讀寫文件

NIO 2.0 提供了帶有緩沖區的讀寫輔助方法,使用起來也非常的簡單。可以通過 Files.newBufferedWriter() 獲取一個文件緩沖輸入流,并通過 write() 方法寫入數據;然后通過 Files.newBufferedReader() 獲取一個文件緩沖輸出流,通過 readLine() 方法讀出數據。代碼示例如下。

Path file = Paths.get("沉默王二.txt");
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
 writer.write("一個有趣的程序員");
} catch (Exception e) {
 e.printStackTrace();
}
try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
 String line;
 while ((line = reader.readLine()) != null) {
 System.out.println(line);
 }
} catch (Exception e) {
 e.printStackTrace();
}

06、重要:異步 I/O 操作

實話實說吧,上面提到的那些都算是 NIO 2.0 的甜點,而異步 I/O 操作(也稱 AIO)才算是真正重要的內容。異步 I/O 操作可以充分利用多核 CPU 的特點,不需要再像以前那樣啟動一個線程來對 I/O 進行處理,免得阻塞了主線程的其他操作。

異步 I/O 操作的核心概念是發起非阻塞方式的 I/O 操作,當 I/O 操作完成時通知??梢苑譃閮煞N形式:Future 和 Callback。如果我們希望主線程發起 I/O 操作并輪循等待結果時,一般使用 Future 的形式;而 Callback 的基本思想是主線程派出一個偵查員(CompletionHandler)到獨立的線程中執行 I/O 操作,操作完成后,會觸發偵查員的 completed 或者 failed 方法。

1)Future

先來看一個示例,代碼如下:

public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
 Path file = Paths.get("沉默王二.txt");
 AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);
 Future<Integer> result = channel.read(ByteBuffer.allocate(100_000), 0);
 while (!result.isDone()) {
 System.out.println("主線程繼續做事情");
 }
 Integer bytesRead = result.get();
 System.out.println(bytesRead);
}

1)通過 AsynchronousFileChannel.open() 打開一個異步文件通道 channel。

2)用 Future 來保存從通道中讀取的結果。

3)通過 isDone() 輪循判斷異步 I/O 操作是否完成,如果沒有完成的話,主線程可以繼續做自己的事情。

2)Callback

先來看一個示例,代碼如下:

public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
 Path file = Paths.get("沉默王二.txt");
 AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);
 channel.read(ByteBuffer.allocate(100_000), 0, null, new CompletionHandler<Integer, ByteBuffer>() {
 public void completed(Integer result, ByteBuffer attachment) {
 System.out.println(result);
 }
 public void failed(Throwable exc, ByteBuffer attachment) {
 System.out.println(exc.getMessage());
 }
 });
 System.out.println("主線程繼續做事情");
}

1)通過 AsynchronousFileChannel.open() 打開一個異步文件通道 channel。

2)在 read 方法中使用匿名內部類的形式啟用 CompletionHandler,然后實現 CompletionHandler 的兩個監聽方法,completed 的時候打印結果,failed 的時候打印異常信息。

不管是 Future 形式還是 Callback 形式,總之異步 I/O 是一個強大的特性,可以保證在處理大文件時性能不受到顯著的影響。

原文地址:https://www.cnblogs.com/qing-gee/p/11231258.html

分享到:
標簽:Java NIO
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定