日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 7 中 NIO.2 的使用——第四节 文件和目录

發(fā)布時間:2023/12/18 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 7 中 NIO.2 的使用——第四节 文件和目录 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  Files類提供了很多方法用于檢查在于你真正實際去操作一個文件或目錄。這些方法強烈推薦,也非常有用,也能避免很多異常的發(fā)生。例如,一個很好的習慣就是在你試著移動一個文件從一個地方到另一個地方的時候,先檢查文件是否存在。

  檢查一個文件或目錄是否存在

  在前面的例子中已經(jīng)演示到,Path實例能夠有效的映射到一個文件或是目錄甚至這個文件或目錄物理上根本不存在。再是,Path的很多方法不會實際操作文件本身就能成功地應(yīng)用。所以,事先判斷一個目錄或是文件存在就顯得非常重要。下面有兩個方法用來判斷文件是否存在。

  • exists():檢查一個文件是否存在
  • notExists(): 檢查一個文件是否不存在

  這兩個方法都包含兩個參數(shù),第一個參數(shù)是path實例,第二個參數(shù)符號連接的文件是否處理。exist()方法返回 true如果文件存在。下下面代碼:

Path path = FileSystems.getDefault().getPath("C:/rafaelnadal/tournaments/2009","AEGON.txt");…boolean path_exists = Files.exists(path, new LinkOption[]{LinkOption.NOFOLLOW_LINKS});

  注意:!Files.exists(…)與Files.notExists(…)方法不是等價的,notExists()不是exists()方法的補充。

  檢查文件的可訪問性

  一個很好的習慣就是在訪問一個文件前先檢查它的可訪問級別,可以使用isReadable(), isWritable(), isExecutable()這些方法。在傳遞一個路徑被確認后,如果文件可讀,可寫,可執(zhí)行,那么虛擬機將有權(quán)限去訪問這個文件。

  另外,可以使用isRegularFile()方法在判斷文件是不是一個正常的文件。正常的文件是指沒有特別的特性(例如,不是符號鏈接,不是目錄等),包含真實的數(shù)據(jù)(例如二進制文件)。上代碼。

C:\rafaelnadal\tournaments\2009 directory (the file must exist) looks like the following:Path path = FileSystems.getDefault().getPath("C:/rafaelnadal/tournaments/2009","AEGON.txt");boolean is_readable = Files.isReadable(path);boolean is_writable = Files.isWritable(path);boolean is_executable = Files.isExecutable(path);boolean is_regular = Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS);if ((is_readable) && (is_writable) && (is_executable) && (is_regular)) {System.out.println("The checked file is accessible!");} else {System.out.println("The checked file is not accessible!");}

  或者像下面這樣的代碼:

boolean is_accessible = Files.isRegularFile(path) & Files.isReadable(path) & Files.isExecutable(path) & Files.isWritable(path);if (is_accessible) {System.out.println("The checked file is accessible!");} else {System.out.println("The checked file is not accessible!");}

?  檢查兩個路徑是否指向同一相同文件

  在以前的章節(jié)中,有可以看到如何去檢查一個符號鏈接和目標文件是否是同一個文件。還有一個常用的測試就是你你可以使用isSameFile()方法去檢查不同的Paths的表達是否指向同一個文件。例如,一個相對路徑和一個絕對路徑可能指向同一個文件。假設(shè)有一文件的路徑為C:\rafaelnadal\tournaments\2009\MutuaMadridOpen.txt,有下面三種Path的表達方式。

Path path_1 = FileSystems.getDefault().getPath("C:/rafaelnadal/tournaments/2009","MutuaMadridOpen.txt"); Path path_2 = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/2009", "MutuaMadridOpen.txt"); Path path_3 = FileSystems.getDefault().getPath("/rafaelnadal/tournaments/dummy/../2009", "MutuaMadridOpen.txt");try {boolean is_same_file_12 = Files.isSameFile(path_1, path_2);boolean is_same_file_13 = Files.isSameFile(path_1, path_3);boolean is_same_file_23 = Files.isSameFile(path_2, path_3);System.out.println("is same file 1&2 ? " + is_same_file_12);System.out.println("is same file 1&3 ? " + is_same_file_13);System.out.println("is same file 2&3 ? " + is_same_file_23);} catch (IOException e) {System.err.println(e);}

  輸出結(jié)果為:

is same file 1&2 ? true

is same file 1&3 ? true

is same file 2&3 ? true

  檢查文件是否可見。

  如果你需要找出一個文件是否可見,可以使用Files.isHidden()方法,需要注意的是,“hidden”這個概念是依賴平臺的。

Path path = FileSystems.getDefault().getPath("C:/rafaelnadal/tournaments/2009", "MutuaMadridOpen.txt");…try {boolean is_hidden = Files.isHidden(path);System.out.println("Is hidden ? " + is_hidden);} catch (IOException e) {System.err.println(e);}

  --------------------------------------------------------------------------------------------------------------------------------

  創(chuàng)建和讀取目錄

  當我們需要創(chuàng)建和讀取一個目錄時,NIO.2提供了一些類方法在Files類中。在這一節(jié)中,你將會發(fā)現(xiàn)如何列出文件系統(tǒng)的根,創(chuàng)建目錄以及臨時目錄,列出目錄里的內(nèi)容,還可以對目錄進行過濾。

  列出文件系統(tǒng)的根目錄

  在Java 6 中,文件系統(tǒng)的根目錄被抽取出一個存放File對象的數(shù)組中,從Java 7 開始,NIO.2 會把根目錄作為Path對象的Iterable,通過getRootDirectories()方法返回這個Iterable接口。

Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();for (Path name : dirs) {System.out.println(name);}

  可能的輸出結(jié)果是:

  C:\

  D:\

  E:\

  創(chuàng)建一個新的目錄

  直接上代碼。

Path newdir = FileSystems.getDefault().getPath("C:/rafaelnadal/tournaments/2010/");…try {Files.createDirectory(newdir);} catch (IOException e) {System.err.println(e);}

  當然,也可以在創(chuàng)建目錄時設(shè)置權(quán)限信息:

Path newdir = FileSystems.getDefault().getPath("/home/rafaelnadal/tournaments/2010/");…Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);try {Files.createDirectory(newdir, attr);} catch (IOException e) {System.err.println(e);}

  注意,如果要創(chuàng)建的目錄存在,則?createDirectory()方法會拋出異常。

  有的時候,我們需要多層的目錄,例如\statistics\win\prizes,當然你可以使用createDirectory()方法,其實還可以優(yōu)雅地使用Files.createDirectories()方法,

Path newdir= FileSystems.getDefault().getPath("C:/rafaelnadal/", "statistics/win/prizes");…try {Files.createDirectories(newdir);} catch (IOException e) {System.err.println(e);}

  列出目錄里的內(nèi)容

Path path = Paths.get("C:/rafaelnadal/tournaments/2009");//no filter appliedSystem.out.println("\nNo filter applied:");try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {for (Path file : ds) {System.out.println(file.getFileName());}}catch(IOException e) {System.err.println(e);}

  使用正則表達式列出目錄里的內(nèi)容

Path path = Paths.get("C:/rafaelnadal/tournaments/2009");…//glob pattern appliedSystem.out.println("\nGlob pattern applied:");try (DirectoryStream<Path> ds = Files.newDirectoryStream(path, "*.{png,jpg,bmp}")) {for (Path file : ds) {System.out.println(file.getFileName());}} catch (IOException e) {System.err.println(e);}

  用戶自定義過濾器列出目錄里的內(nèi)容

  如果正則表達式不能滿足你的需求,你也可以自定義自己的過濾器,這個任務(wù)很簡單,只需要繼承DirectoryStream.Filter<T>接口即可。此接口有accept()方法,一個Path是接受還是拒絕完全基于你的實現(xiàn)。下面的例子,只列出給定目錄下的所有目錄。

Path path = Paths.get("C:/rafaelnadal/tournaments/2009");…//user-defined filter - only directories are acceptedDirectoryStream.Filter<Path> dir_filter = new DirectoryStream.Filter<Path>() {public boolean accept(Path path) throws IOException {return (Files.isDirectory(path, NOFOLLOW_LINKS));}}; System.out.println("\nUser defined filter applied:");try (DirectoryStream<Path> ds = Files.newDirectoryStream(path, dir_filter)) {for (Path file : ds) {System.out.println(file.getFileName());}} catch (IOException e) {System.err.println(e);}

  還有如下自定義的過濾器。

    1.列出文件或目錄大小超過200kb的列表。

public boolean accept(Path path) throws IOException {return (Files.size(path) > 204800L);}};

    2.列出只有今天修改的文件的列表。

DirectoryStream.Filter<Path> time_filter = new DirectoryStream.Filter<Path>() {public boolean accept(Path path) throws IOException {long currentTime = FileTime.fromMillis(System.currentTimeMillis()).to(TimeUnit.DAYS);long modifiedTime = ((FileTime) Files.getAttribute(path, "basic:lastModifiedTime", NOFOLLOW_LINKS)).to(TimeUnit.DAYS);if (currentTime == modifiedTime) {return true;}return false;}};

    3.只列出隱藏的文件或目錄

DirectoryStream.Filter<Path> hidden_filter = new DirectoryStream.Filter<Path>() {public boolean accept(Path path) throws IOException {return (Files.isHidden(path));}};

  -----------------------------------------------------------------------------------------------------------------------------

?  創(chuàng)建,讀取和寫文件

  一個Stream表示輸入源或是輸出目的地。stream支持不同種類的數(shù)據(jù),例如字符串,字節(jié),基本數(shù)據(jù)類型,本地化字符還有對象。在一個無緩沖的流,每個讀或?qū)懻埱笥傻讓硬僮飨到y(tǒng)直接處理,而在有緩存的流中,數(shù)據(jù)從內(nèi)存中稱之為緩沖區(qū)的地方讀取,只有當緩沖區(qū)為空的時候本地輸入API會被調(diào)用。類似的,緩存的輸出流把數(shù)據(jù)寫入到緩沖區(qū)中,只有緩沖區(qū)寫滿以后本地輸出API才會被調(diào)用。當緩沖區(qū)輸出完沒有等待填滿時,外我們說這個緩沖區(qū)是清空的。

  使用標準的打開選項

  從NIO.2 開始,文件的創(chuàng)建,讀取和寫入操作都支持一個可選參數(shù)——OpenOption,它用來配置外面如何打開或是創(chuàng)建一個文件。實際上OpenOption是java.nio.file包中一個接口,它有兩個實現(xiàn)類:LinkOption 和 StandardOpenOption。下面就是選項枚舉。

READ以讀取方式打開文件
WRITE  已寫入方式打開文件
CREATE如果文件不存在,創(chuàng)建
CREATE_NEW如果文件不存在,創(chuàng)建;若存在,異常。
APPEND在文件的尾部追加
DELETE_ON_CLOSE當流關(guān)閉的時候刪除文件
TRUNCATE_EXISTING把文件設(shè)置為0字節(jié)
SPARSE文件不夠時創(chuàng)建新的文件
SYNC同步文件的內(nèi)容和元數(shù)據(jù)信息隨著底層存儲設(shè)備
DSYNC同步文件的內(nèi)容隨著底層存儲設(shè)備

?

?

?

?

?

?

?

?

?

?

?  創(chuàng)建一個文件

  創(chuàng)建文件和創(chuàng)建目錄類似,可以使用Files.createFile()方法,也可以在創(chuàng)建的時候添加權(quán)限信息。

Path newfile = FileSystems.getDefault().getPath("C:/rafaelnadal/tournaments/2010/SonyEricssonOpen.txt");…try {Files.createFile(newfile);} catch (IOException e) {System.err.println(e);}

  創(chuàng)建帶有權(quán)限的文件.

Path newfile = FileSystems.getDefault().getPath("/home/rafaelnadal/tournaments/2010/SonyEricssonOpen.txt");Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);try {Files.createFile(newfile, attr);} catch (IOException e) {System.err.println(e);}

  寫入一個小文件

  NIO.2提供了非常優(yōu)雅的方式去寫入小的二進制或是文本文件。使用Files.write()方法來創(chuàng)建。

  使用write()方法寫入bytes

Path ball_path = Paths.get("C:/rafaelnadal/photos", "ball.png");…byte[] ball_bytes = new byte[]{(byte)0x89,(byte)0x50,(byte)0x4e,(byte)0x47,(byte)0x0d,(byte)0x0a,(byte)0x1a,(byte)0x0a,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x0d,(byte)0x49,(byte)0x48,(byte)0x44,(byte)0x52,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x10,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x10,(byte)0x08,(byte)0x02,(byte)0x00, …(byte)0x49,(byte)0x45,(byte)0x4e,(byte)0x44,(byte)0xae,(byte)0x42,(byte)0x60,(byte)0x82 };try {Files.write(ball_path, ball_bytes);} catch (IOException e) {System.err.println(e);}

  按行寫入文件

Path rf_wiki_path = Paths.get("C:/rafaelnadal/wiki", "wiki.txt");…Charset charset = Charset.forName("UTF-8");ArrayList<String> lines = new ArrayList<>();lines.add("\n");lines.add("Rome Masters - 5 titles in 6 years");lines.add("Monte Carlo Masters - 7 consecutive titles (2005-2011)");lines.add("Australian Open - Winner 2009");lines.add("Roland Garros - Winner 2005-2008, 2010, 2011");lines.add("Wimbledon - Winner 2008, 2010");lines.add("US Open - Winner 2010");try {Files.write(rf_wiki_path, lines, charset, StandardOpenOption.APPEND);} catch (IOException e) {System.err.println(e);}

?  讀取一個小文件

  NIO.2 提供了兩個方法Files.readAllBytes()?和 Files.readAllLines()方法用來讀取小的字節(jié)或是文本文件。很簡單,直接看代碼。

Path ball_path = Paths.get("C:/rafaelnadal/photos", "ball.png");…try {byte[] ballArray = Files.readAllBytes(ball_path); } catch (IOException e) {System.out.println(e);} Path wiki_path = Paths.get("C:/rafaelnadal/wiki", "wiki.txt");…Charset charset = Charset.forName("ISO-8859-1");try {List<String> lines = Files.readAllLines(wiki_path, charset);for (String line : lines) {System.out.println(line);}} catch (IOException e) {System.out.println(e);}

  根據(jù)官方文檔,該方法識別以下行認為是結(jié)束符:

  • \u000D followed by \u000A: 回車接著換行
  • \u000A: 換行
  • \u000D:回車

  使用緩存流進行工作

  在多數(shù)操作系統(tǒng)中,系統(tǒng)調(diào)用文件的讀寫是一件非常昂貴的操作。在緩沖的方法區(qū)和操作系統(tǒng)之間提供了一塊內(nèi)存區(qū)域很好的解決了這個問題。

在調(diào)用本地API之前,這些方法在操作系統(tǒng)和應(yīng)用程序之間的緩存中獲取或設(shè)置數(shù)據(jù)。這樣大大地提高了效率因為它減少了調(diào)用系統(tǒng)的次數(shù)。只有在緩沖區(qū)為空或是滿的時候,才會訪問硬盤,根據(jù)讀取或?qū)懭氩僮鳌IO.2提供了兩個通過緩存讀取和寫入文件的方法:Files.newBufferedReader() 和Files.newBufferedWriter(),相應(yīng)的,這兩個方法會得到Path實例并返回BufferedReader 或 BufferedWriter 實例。

  使用?newBufferedWriter()方法

?  不多說,上代碼。

Path wiki_path = Paths.get("C:/rafaelnadal/wiki", "wiki.txt");…Charset charset = Charset.forName("UTF-8");String text = "\nVamos Rafa!";try (BufferedWriter writer = Files.newBufferedWriter(wiki_path, charset, StandardOpenOption.APPEND)) {writer.write(text);} catch (IOException e) {System.err.println(e);}

  使用newBufferedReader()方法

Path wiki_path = Paths.get("C:/rafaelnadal/wiki", "wiki.txt");…Charset charset = Charset.forName("UTF-8");try (BufferedReader reader = Files.newBufferedReader(wiki_path, charset)) {String line = null;while ((line = reader.readLine()) != null) {System.out.println(line);}} catch (IOException e) {System.err.println(e);}

?  使用無緩存的流工作

  可以使用NIO.2直接獲取無緩存的流也可以使用java.io的API中的包裝類轉(zhuǎn)換成緩存流。使用無緩存的流的方法有Files.newInputStream()(從一個文件中讀取到輸入流中),Files.newOutputStream()方法(從輸出流中寫入到文件中)。

  使用newOutputStream() 方法

  這個方法獲取指向文件的路徑和說明文件時如何打開的,它會返回一個線程安全的無緩存的劉對象,用來寫入字節(jié)到文件中。

  上菜。

//C:\rafaelnadal\equipment\racquet.txt (the file doesn’t initially exist, but it will be automatically created because no options are specified):Path rn_racquet = Paths.get("C:/rafaelnadal/equipment", "racquet.txt");String racquet = "Racquet: Babolat AeroPro Drive GT";byte data[] = racquet.getBytes();try (OutputStream outputStream = Files.newOutputStream(rn_racquet)) {outputStream.write(data);} catch (IOException e) {System.err.println(e);}

  此外,如果你有更好的主意使用緩存的流代替上面的代碼,推薦使用基于java.io的API的轉(zhuǎn)換,正如下面的代碼,

Path rn_racquet = Paths.get("C:/rafaelnadal/equipment", "racquet.txt");String string = "\nString: Babolat RPM Blast 16";try (OutputStream outputStream = Files.newOutputStream(rn_racquet, StandardOpenOption.APPEND);BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) {writer.write(string);} catch (IOException e) {System.err.println(e);}

  使用?newInputStream()方法

//The following code snippet reads the content of the file racquet.txt (the file must exist): Path rn_racquet = Paths.get("C:/rafaelnadal/equipment", "racquet.txt");…int n; try (InputStream in = Files.newInputStream(rn_racquet)) {while ((n = in.read()) != -1) {System.out.print((char)n); }} catch (IOException e) {System.err.println(e);}

  從此而外,你也可以把一個無緩存的流轉(zhuǎn)換成緩存流,下面的代碼跟上面的代碼實現(xiàn)了相同的功能,但是它更加高效。

Path rn_racquet = Paths.get("C:/rafaelnadal/equipment", "racquet.txt");…try (InputStream in = Files.newInputStream(rn_racquet);BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {String line = null;while ((line = reader.readLine()) != null) {System.out.println(line);}} catch (IOException e) {System.err.println(e);}

  ------------------------------------------------------------------------------------------------------------------------

?  創(chuàng)建臨時目錄和文件

  一個臨時目錄用來存放臨時文件。臨時目錄的存放位置依賴于操作系統(tǒng)。在Windows下,臨時目錄可以通過“TEMP”環(huán)境變量來設(shè)置,通常的位置是:C:\Temp, %Windows%\Temp,或者在每個用戶的:Local Settings\Temp。而Unix/Linux的臨時目錄為:/tmp 和/var/tmp。

  創(chuàng)建一個臨時目錄

  在NIO.2中通過createTempDirectory()方法用來創(chuàng)建一個臨時目錄,創(chuàng)建默認的操作系統(tǒng)的臨時目錄可以調(diào)用createTempDirectory()兩個參數(shù)的方法:前一個用來設(shè)置目錄的名字的前綴(可以為null),后一個可選參數(shù)用來設(shè)置文件屬性。

String tmp_dir_prefix = "nio_";try {//passing null prefixPath tmp_1 = Files.createTempDirectory(null);System.out.println("TMP: " + tmp_1.toString());//set a prefixPath tmp_2 = Files.createTempDirectory(tmp_dir_prefix);System.out.println("TMP: " + tmp_2.toString());} catch (IOException e) {System.err.println(e);}

  則輸出結(jié)果為:

TMP: C:\Users\Leo\AppData\Local\Temp\3238630399269555448

TMP: C:\Users\Leo\AppData\Local\Temp\nio_1097550355199661257

  如果你不知道系統(tǒng)的默認臨時目錄的路徑,也可以使用下面的代碼:

//output: C:\Users\Leo\AppData\Local\Temp\String default_tmp = System.getProperty("java.io.tmpdir");System.out.println(default_tmp);

  更進一步,你也可以通過createTempDirectory()方法自定義臨時目錄的路徑,

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp/");String tmp_dir_prefix = "rafa_";try {if (Files.notExists(basedir)) {Path dir = Files.createDirectories(basedir);// create a tmp directory in the base dirPath tmp = Files.createTempDirectory(dir, tmp_dir_prefix);System.out.println("TMP: " + tmp.toString());}} catch (IOException e) {System.err.println(e);}

  輸出結(jié)果為:

TMP: C:\rafaelnadal\tmp\rafa_1753327229539718259

  使用Shutdown-Hook刪除臨時文件

  大部分操作系統(tǒng)都會自動地刪除臨時目錄(如果不能,你可以使用多種清理軟件),但是,有時候你需要程序級別的控制文件的刪除過程。createTempDirectory()方法只是完成了一半的工作,因為刪除工作由你負責。為了這一原因你可以shutdown-hook機制,這個機制用來執(zhí)行任何資源的清理或者保持在JVM關(guān)閉之前生效。這個鉤子可以是Java線程的實現(xiàn)。Thread的run()方法可以在JVM關(guān)閉時執(zhí)行操作。

    Figure 4-1. The simple flow design of a shutdown-hook

Runtime.getRuntime().addShutdownHook(new Thread() {@Overridepublic void run() {System.out.println("Shutdown-hook activated ...");//… here, cleanup/save resources System.out.println("Shutdown-hook successfully executed ...");}});

  shutdown-hook機制是一個很好的方法用來解決JVM關(guān)閉時刪除臨時目錄的問題。同時你也知道,如果目錄不為空的話是無法刪除的。所以你需要循環(huán)每一層目錄刪除每一個文件直至每個目錄為空再刪除目錄本身。

  使用deleteOnExit() 方法刪除臨時目錄

  另一種刪除臨時目錄的解決方法是調(diào)用deleteOnExit()方法,這個方法在java.io.Fi類中。它將在JVM關(guān)閉時刪除傳遞的文件或目錄參數(shù)。因為這個方法需要被每個目錄和文件調(diào)用,所以它最不吸引人的地方就是需要為每個臨時實體消耗內(nèi)存。

  注意,如果你的系統(tǒng)需要長時間運行或者在很短的時間內(nèi)需要創(chuàng)建很多文件和目錄,則使用deleteOnExit()是個很壞的主意。它需要占用大量內(nèi)存即使JVM退出后還沒有釋放。

  下面演示deleteOnExit()方法的使用。

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp/");String tmp_dir_prefix = "rafa_";try {//create a tmp directory in the base dirPath tmp_dir = Files.createTempDirectory(basedir, tmp_dir_prefix);File asFile = tmp_dir.toFile();asFile.deleteOnExit();//simulate some I/O operations over the temporary file by sleeping 10 seconds//when the time expires, the temporary file is deleted //EACH CREATED TEMPORARY ENTRY SHOULD BE REGISTERED FOR DELETE ON EXITThread.sleep(10000);//operations done } catch (IOException | InterruptedException e) {System.err.println(e);}

  創(chuàng)建臨時文件

  不羅嗦,一些概念跟創(chuàng)建臨時目錄一樣,直接上代碼。

String tmp_file_prefix = "rafa_";String tmp_file_sufix=".txt";try {//passing null prefix/suffixPath tmp_1 = Files.createTempFile(null,null);System.out.println("TMP: " + tmp_1.toString());//set a prefix and a suffixPath tmp_2 = Files.createTempFile(tmp_file_prefix, tmp_file_sufix);System.out.println("TMP: " + tmp_2.toString());} catch (IOException e) {System.err.println(e);}

  同樣,你也可以自定義臨時文件的目錄。

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp");String tmp_file_prefix = "rafa_";String tmp_file_sufix=".txt";try {Path tmp_3 = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix);System.out.println("TMP: " + tmp_3.toString());} catch (IOException e) {System.err.println(e);}

  使用?Shutdown-Hook機制刪除臨時文件

  下面代碼在C:\rafaelnadal\tmp下創(chuàng)建臨時文件,等待10秒鐘后,當JVM退出后刪除臨時文件。

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp");String tmp_file_prefix = "rafa_";String tmp_file_sufix = ".txt";try {final Path tmp_file = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix);Runtime.getRuntime().addShutdownHook(new Thread() {@Overridepublic void run() {System.out.println("Deleting the temporary file ...");try {Files.delete(tmp_file);} catch (IOException e) {System.err.println(e);}System.out.println("Shutdown hook completed...");}});//simulate some I/O operations over the temporary file by sleeping 10 seconds//when the time expires, the temporary file is deleted Thread.sleep(10000);//operations done } catch (IOException | InterruptedException e) {System.err.println(e);}

  使用?deleteOnExit() 方法刪除臨時文件

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp");String tmp_file_prefix = "rafa_";String tmp_file_sufix = ".txt";try {final Path tmp_file = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix);File asFile = tmp_file.toFile();asFile.deleteOnExit();//simulate some I/O operations over the temporary file by sleeping 10 seconds//when the time expires, the temporary file is deletedThread.sleep(10000);//operations done } catch (IOException | InterruptedException e) {System.err.println(e);}

  使用DELETE_ON_CLOSE枚舉參數(shù)刪除臨時文件

  另一種比較獨特的刪除臨時文件的方式是使用DELETE_ON_CLOSE選項。它會在流關(guān)閉的時候刪除文件。

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp");String tmp_file_prefix = "rafa_";String tmp_file_sufix = ".txt";Path tmp_file = null;try {tmp_file = Files.createTempFile(basedir, tmp_file_prefix, tmp_file_sufix);} catch (IOException e) {System.err.println(e);}try (OutputStream outputStream = Files.newOutputStream(tmp_file, StandardOpenOption.DELETE_ON_CLOSE);BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) {//simulate some I/O operations over the temporary file by sleeping 10 seconds//when the time expires, the temporary file is deleted Thread.sleep(10000);//operations done} catch (IOException | InterruptedException e) {System.err.println(e);}

  除此而外,你甚至不用調(diào)用createTempFile()方法,當你使用CREATE選項與DELETE_ON_CLOSE組合使用時:

String tmp_file_prefix = "rafa_";String tmp_file_sufix = ".txt";Path tmp_file = null;tmp_file = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp", tmp_file_prefix + "temporary" + tmp_file_sufix);try (OutputStream outputStream = Files.newOutputStream(tmp_file, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE);BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) {//simulate some I/O operations over the temporary file by sleeping 10 seconds//when the time expires, the temporary file is deleted Thread.sleep(10000);//operations done} catch (IOException | InterruptedException e) {System.err.println(e);}

  目錄或文件的刪除,復(fù)制和移動

  刪除目錄或文件

  NIO.2提供了兩個用來刪除目錄或文件的方法:Files.delete() 和Files.deleteIfExits()。這兩個都接受單一的參數(shù)指定刪除的路徑。但是Files.delete()無返回值,Files.deleteIfExits()返回boolean值根據(jù)文件是否刪除成功。Files.delete()試圖刪除路徑下的文件或目錄,如果刪除失敗,則會拋出以下異常。NoSuchFileException (i路徑不存在), DirectoryNotEmptyException (i目錄不為空), IOException (輸入輸出錯誤發(fā)生), or SecurityException (無刪除權(quán)限)。

Path path = FileSystems.getDefault().getPath("C:/rafaelnadal/photos", "rafa_1.jpg");//delete the filetry {Files.delete(path);} catch (NoSuchFileException | DirectoryNotEmptyException | IOException | SecurityException e) {System.err.println(e);}

  就像名字建議的一樣,Files.deleteIfExists()方法只有在文件存在的時候刪除,這就意味著如果文件不存在(代替了拋出NoSuchFileException異常)不能刪除的情況下返回boolean值false。這種應(yīng)用在多線程刪除文件的時候非常有用。你不想第一個線程就拋出異常。

try {boolean success = Files.deleteIfExists(path);System.out.println("Delete status: " + success);} catch (DirectoryNotEmptyException | IOException | SecurityException e) {System.err.println(e);}

  復(fù)制目錄或文件

  NIO.2中提供了Files.copy()方法來復(fù)制目錄和文件。它提供了StandardCopyOption 和 LinkOption 枚舉下的很多選項作為參數(shù):

  • REPLACE_EXISTING: 如果目標文件存在,則替換;當拷貝符號鏈接文件時,真實文件不拷貝,值拷貝符號鏈接文件。
  • COPY_ATTRIBUTES: 拷貝文件并關(guān)聯(lián)的屬性。
  • NOFOLLOW_LINKS: 不包含符號鏈接的文件或目錄.

  這些枚舉類型靜態(tài)導入到程序中,

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;import static java.nio.file.LinkOption.NOFOLLOW_LINKS;

  在兩個路徑間復(fù)制

Path copy_from = Paths.get("C:/rafaelnadal/grandslam/AustralianOpen", "draw_template.txt");Path copy_to= Paths.get("C:/rafaelnadal/grandslam/USOpen",copy_from.getFileName().toString());try {Files.copy(copy_from, copy_to, REPLACE_EXISTING, COPY_ATTRIBUTES, NOFOLLOW_LINKS);} catch (IOException e) {System.err.println(e);}

?  從一個輸入流中拷貝到文件

Path copy_from = Paths.get("C:/rafaelnadal/grandslam/AustralianOpen", "draw_template.txt");Path copy_to = Paths.get("C:/rafaelnadal/grandslam/Wimbledon", "draw_template.txt");try (InputStream is = new FileInputStream(copy_from.toFile())) {Files.copy(is, copy_to, REPLACE_EXISTING);} catch (IOException e) {System.err.println(e);}

  文件輸入流可能來自不同的方式。例如下面的代碼中文件來自于互聯(lián)網(wǎng)的URL。

Path copy_to = Paths.get("C:/rafaelnadal/photos/rafa_winner_2.jpg");URI u = URI.create("https://lh6.googleusercontent.com/--udGIidomAM/Tl8KTbYd34I/AAAAAAAAAZw/j2nH24PaZyM/s800/rafa_winner.jpg");try (InputStream in = u.toURL().openStream()) {Files.copy(in, copy_to);} catch (IOException e) {System.err.println(e);}

  從一個文件拷貝到輸出流

Path copy_from = Paths.get("C:/rafaelnadal/grandslam/AustralianOpen", "draw_template.txt");Path copy_to = Paths.get("C:/rafaelnadal/grandslam/RolandGarros", "draw_template.txt");try (OutputStream os = new FileOutputStream(copy_to.toFile())) {Files.copy(copy_from, os);} catch (IOException e) {System.err.println(e);}

  移動文件和目錄

  在這部分,你將會學習到 如何使用Files.move()方法移動目錄和文件。這個方法有一可選參數(shù)用來指定一枚舉類型:

  • REPLACE_EXISTING:若目標文件存在,則替換.
  • ATOMIC_MOVE: 執(zhí)行的文件將被作為一個原子操作,保證任何過程監(jiān)控文件的目錄將會訪問一個完整的文件。

  默認情況下(沒有明確指定選項) move()嘗試移動文件到目標文件,如果目標文件存在,則會失敗。除非源文件與目標文件是同一文件(isSameFile()返回 true),這種情況方法不會生效。

Path movefrom = FileSystems.getDefault().getPath("C:/rafaelnadal/rafa_2.jpg");Path moveto = FileSystems.getDefault().getPath("C:/rafaelnadal/photos/rafa_2.jpg");try {Files.move(movefrom, moveto, StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {System.err.println(e);}

  如果你不想hard-code移動文件的名字,可以使用Path.resolve()方法,通過這種方法,你可以直接從需要移動的路徑中抽取文件名字給移動文件的名字。

   Path movefrom = FileSystems.getDefault().getPath("C:/rafaelnadal/rafa_2.jpg");Path moveto_dir = FileSystems.getDefault().getPath("C:/rafaelnadal/photos");System.out.println(moveto_dir.resolve(movefrom.getFileName())); // C:\rafaelnadal\photos\rafa_2.jpgtry {Files.move(movefrom, moveto_dir.resolve(movefrom.getFileName()), StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {System.err.println(e);}

  重命名文件

  這開起來有些詭異,可以通過Files.move() 和Path.resolveSibling() 重命名一個文件。

Path movefrom = FileSystems.getDefault().getPath("C:/rafaelnadal/photos/rafa_2.jpg");try {Files.move(movefrom, movefrom.resolveSibling("rafa_2_renamed.jpg"), StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {System.err.println(e);}

  完。

?

?

?

?

  

  

轉(zhuǎn)載于:https://www.cnblogs.com/IcanFixIt/p/4838375.html

總結(jié)

以上是生活随笔為你收集整理的Java 7 中 NIO.2 的使用——第四节 文件和目录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产91精品一区二区麻豆亚洲 | 波多野结av衣东京热无码专区 | 欧美精品hd | 欧美久久一区二区 | 真性中出| 熊猫成人网 | 黄色成人一级片 | 夜夜嗨一区二区三区 | 51成人 | 性网址 | 狠狠狠狠狠狠狠 | 国产熟妇一区二区三区四区 | 亚洲综合一区在线 | 成人看片在线观看 | 成人黄色免费在线观看 | 精品国产欧美日韩 | 亚州av综合色区无码一区 | 午夜天堂视频 | 久久久久久午夜 | 草逼视频免费看 | 欧美福利视频 | 嫩草视频在线观看视频 | 日本视频在线观看免费 | 久久国产精品影视 | 欧洲一区二区在线观看 | 男女黄床上色视频免费的软件 | 亚洲经典一区二区 | 韩国美女视频在线观看18 | 在线观看国产一级片 | 日韩视频免费观看高清 | 天天插天天射天天干 | 在线日本中文字幕 | 男女www | 国产又粗又猛又爽又黄的视频小说 | 日韩一区二区三区精品视频 | 国产xxxx做受视频 | 久久午夜夜伦鲁鲁片 | 欧美一级高清片 | 欧美色图在线视频 | 亚洲色图35p | 日本黄色网页 | 国产九九热 | 欧美成人xxx | 国产日批| 自拍偷拍一区 | 麻豆69xxnxxporn| 在线播放小视频 | 大地资源二中文在线影视免费观看 | 东南亚毛片 | 欧美熟妇另类久久久久久多毛 | 国产高清视频 | 精品成人免费一区二区在线播放 | 女女av在线 | 国产精品国产三级国产普通话对白 | 国产区精品视频 | 超碰在线观看97 | 新婚之夜玷污岳丰满少妇在线观看 | 一级香蕉视频在线观看 | 无码国产精品一区二区免费16 | 国产免费播放 | 美女18网站| 成人青青草 | av香港经典三级级 在线 | 亲吻刺激视频 | 1000部拍拍拍18勿入免费视频 | 激情999| 国产剧情一区 | 亚洲天天视频 | 清冷男神被c的合不拢腿男男 | 欧美啪啪小视频 | 自拍偷拍亚洲图片 | 欧美一级片免费观看 | 国产精品一区二区三区在线播放 | 好吊妞这里只有精品 | 岳乳丰满一区二区三区 | 国产精品网址 | 性猛交xxxx乱大交3 | 精品久久久久一区 | 成人深夜福利在线观看 | 日本中文视频 | 国产丝袜美腿一区二区三区 | √天堂资源在线 | 国产一区二区小说 | 日韩黄| 九九久久国产精品 | 免费不卡视频 | 一区在线视频 | 欧美黄色大片在线观看 | www中文在线 | 777精品久无码人妻蜜桃 | 亚洲欧美激情另类校园 | 日本少妇高潮 | 亚洲国产片 | 午夜影院久久 | 黄色的一级片 | 日本二区视频 | 在线免费福利视频 | 狠狠操狠狠爱 | 亚洲天天av |