亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Java7中NIO.2的使用——第四節文件和目錄

2019-11-14 15:32:39
字體:
來源:轉載
供稿:網友

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

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

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

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

  這兩個方法都包含兩個參數,第一個參數是path實例,第二個參數符號連接的文件是否處理。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()這些方法。在傳遞一個路徑被確認后,如果文件可讀,可寫,可執行,那么虛擬機將有權限去訪問這個文件。

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

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.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!"); }

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

  在以前的章節中,有可以看到如何去檢查一個符號鏈接和目標文件是否是同一個文件。還有一個常用的測試就是你你可以使用isSameFile()方法去檢查不同的Paths的表達是否指向同一個文件。例如,一個相對路徑和一個絕對路徑可能指向同一個文件。假設有一文件的路徑為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); }

  輸出結果為:

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); }

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

  創建和讀取目錄

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

  列出文件系統的根目錄

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

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

  可能的輸出結果是:

  C:/

  D:/

  E:/

  創建一個新的目錄

  直接上代碼。

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

  當然,也可以在創建目錄時設置權限信息:

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); }

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

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

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

  列出目錄里的內容

Path path = Paths.get("C:/rafaelnadal/tournaments/2009"); //no filter applied System.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); }

  使用正則表達式列出目錄里的內容

Path path = Paths.get("C:/rafaelnadal/tournaments/2009"); … //glob pattern applied System.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); }

  用戶自定義過濾器列出目錄里的內容

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

Path path = Paths.get("C:/rafaelnadal/tournaments/2009"); … //user-defined filter - only directories are accepted DirectoryStream.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));   } };

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

   創建,讀取和寫文件

  一個Stream表示輸入源或是輸出目的地。stream支持不同種類的數據,例如字符串,字節,基本數據類型,本地化字符還有對象。在一個無緩沖的流,每個讀或寫請求由底層操作系統直接處理,而在有緩存的流中,數據從內存中稱之為緩沖區的地方讀取,只有當緩沖區為空的時候本地輸入API會被調用。類似的,緩存的輸出流把數據寫入到緩沖區中,只有緩沖區寫滿以后本地輸出API才會被調用。當緩沖區輸出完沒有等待填滿時,外我們說這個緩沖區是清空的。

  使用標準的打開選項

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

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

 

 

 

 

 

 

 

 

 

 

   創建一個文件

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

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

  創建帶有權限的文件.

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提供了非常優雅的方式去寫入小的二進制或是文本文件。使用Files.write()方法來創建。

  使用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()方法用來讀取小的字節或是文本文件。很簡單,直接看代碼。

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); }

  根據官方文檔,該方法識別以下行認為是結束符:

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

  使用緩存流進行工作

  在多數操作系統中,系統調用文件的讀寫是一件非常昂貴的操作。在緩沖的方法區和操作系統之間提供了一塊內存區域很好的解決了這個問題。

在調用本地API之前,這些方法在操作系統和應用程序之間的緩存中獲取或設置數據。這樣大大地提高了效率因為它減少了調用系統的次數。只有在緩沖區為空或是滿的時候,才會訪問硬盤,根據讀取或寫入操作。NIO.2提供了兩個通過緩存讀取和寫入文件的方法:Files.newBufferedReader()Files.newBufferedWriter(),相應的,這兩個方法會得到Path實例并返回BufferedReaderBufferedWriter 實例。

  使用 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中的包裝類轉換成緩存流。使用無緩存的流的方法有Files.newInputStream()(從一個文件中讀取到輸入流中),Files.newOutputStream()方法(從輸出流中寫入到文件中)。

  使用newOutputStream() 方法

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

  上菜。

//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的轉換,正如下面的代碼,

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); }

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

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); }

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

   創建臨時目錄和文件

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

  創建一個臨時目錄

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

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

  則輸出結果為:

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

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

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

//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 dir                Path tmp = Files.createTempDirectory(dir, tmp_dir_prefix);                System.out.println("TMP: " + tmp.toString());            }        } catch (IOException e) {            System.err.println(e);        }

  輸出結果為:

TMP: C:/rafaelnadal/tmp/rafa_1753327229539718259

  使用Shutdown-Hook刪除臨時文件

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

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

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

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

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

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

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

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

Path basedir = FileSystems.getDefault().getPath("C:/rafaelnadal/tmp/"); String tmp_dir_prefix = "rafa_"; try {     //create a tmp directory in the base dir     Path 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 EXIT     Thread.sleep(10000);     //operations done } catch (IOException | InterruptedException e) {    System.err.println(e); } 

  創建臨時文件

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

String tmp_file_prefix = "rafa_"; String tmp_file_sufix=".txt"; try {     //passing null prefix/suffix     Path tmp_1 = Files.createTempFile(null,null);     System.out.println("TMP: " + tmp_1.toString());     //set a prefix and a suffix     Path 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下創建臨時文件,等待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() {      @Override     public 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 deleted     Thread.sleep(10000);     //operations done } catch (IOException | InterruptedException e) {     System.err.println(e); } 

  使用DELETE_ON_CLOSE枚舉參數刪除臨時文件

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

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); } 

  除此而外,你甚至不用調用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); } 

  目錄或文件的刪除,復制和移動

  刪除目錄或文件

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

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

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

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

  復制目錄或文件

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

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

  這些枚舉類型靜態導入到程序中,

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

  在兩個路徑間復制

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); }

  文件輸入流可能來自不同的方式。例如下面的代碼中文件來自于互聯網的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()方法移動目錄和文件。這個方法有一可選參數用來指定一枚舉類型:

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

  默認情況下(沒有明確指定選項) 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.jpg        try {         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); }

  完。

 

 

 

 

  

  


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲在线观看视频| 麻豆精品精华液| 亚洲深夜福利视频| 日韩中文字幕在线免费观看| 国产精品白丝av嫩草影院| 最近2019中文字幕一页二页| 欧美尤物巨大精品爽| 日韩中文在线视频| 亚洲精品久久久久国产| 国产精品久久二区| 亚洲一区中文字幕在线观看| 欧美黑人巨大精品一区二区| 国产亚洲精品美女| 成人免费视频xnxx.com| 欧美一级高清免费播放| 欧美日韩国产激情| 日韩精品在线电影| 一个人看的www久久| 久久91超碰青草是什么| 91探花福利精品国产自产在线| 亚洲精品aⅴ中文字幕乱码| 亚洲石原莉奈一区二区在线观看| 国产成人一区二区三区| 亚洲成人av在线| 欧美日韩国产影院| 日韩久久免费电影| 国产精品视频免费在线观看| 中文字幕亚洲无线码a| 91美女片黄在线观| 国产精品在线看| 国产在线98福利播放视频| 成人女保姆的销魂服务| 精品一区二区三区三区| 国产日韩精品一区二区| 久久精品色欧美aⅴ一区二区| 亚洲精品久久久久国产| 久久伊人精品天天| 91深夜福利视频| 久久6精品影院| 亚洲欧美制服中文字幕| 色综合色综合网色综合| 亚洲综合中文字幕在线观看| 91精品国产91久久久久久吃药| 一本色道久久88精品综合| 日韩中文视频免费在线观看| 久久中文字幕国产| 亚洲女成人图区| 国精产品一区一区三区有限在线| 欧美黑人一级爽快片淫片高清| 中文字幕日韩欧美| 国产一级揄自揄精品视频| 国产精品成人一区二区| 最近2019中文字幕在线高清| 亚洲第一综合天堂另类专| 中文字幕亚洲一区二区三区五十路| 韩国精品美女www爽爽爽视频| 精品在线观看国产| 成人美女免费网站视频| 国内精品视频一区| 欧美在线精品免播放器视频| 亚洲理论在线a中文字幕| 疯狂做受xxxx高潮欧美日本| 最近2019好看的中文字幕免费| 成人免费淫片视频软件| 日韩成人中文电影| 欧美亚洲视频一区二区| 亚洲一区二区三区在线免费观看| 国产成人一区二区三区电影| 国产日韩欧美自拍| 亚洲人成在线一二| 91麻豆国产精品| 国产免费观看久久黄| 91精品国产99| 久久69精品久久久久久国产越南| 91精品视频专区| 91av视频在线播放| 最近2019年日本中文免费字幕| 亚洲二区中文字幕| 欧美裸体男粗大视频在线观看| 亚洲精品综合久久中文字幕| 欧美在线日韩在线| 亚洲欧美精品一区| 亚洲最新中文字幕| 精品国内产的精品视频在线观看| 中文字幕亚洲欧美日韩在线不卡| 在线精品高清中文字幕| 97人人模人人爽人人喊中文字| 亚洲a中文字幕| 国产欧美一区二区三区久久人妖| 久久精品电影一区二区| 成人网在线免费看| 国产精品视频久久久久| 欧美午夜女人视频在线| 欧美巨猛xxxx猛交黑人97人| 日韩欧美精品免费在线| 欧美激情精品久久久久久免费印度| 日韩精品中文字幕视频在线| 亚洲国产91精品在线观看| 日韩成人网免费视频| 亚洲精品第一页| 在线日韩av观看| 午夜精品久久久久久久久久久久| 色777狠狠综合秋免鲁丝| 性色av一区二区三区红粉影视| 91免费看片在线| 性视频1819p久久| 成人欧美在线观看| 国产精品久久久久影院日本| 成人精品一区二区三区电影黑人| 欧美电影电视剧在线观看| 久久国产视频网站| 精品国产一区二区三区久久久| 91精品国产综合久久久久久蜜臀| xxxx欧美18另类的高清| 精品久久久视频| 日韩中文字幕视频在线| 久久91精品国产| xxx欧美精品| 久久精品视频网站| 色噜噜狠狠狠综合曰曰曰| 国产精品69久久| 国产精品综合久久久| 亚洲一区中文字幕在线观看| 日韩免费av片在线观看| 亚洲a∨日韩av高清在线观看| 欧美情侣性视频| 91视频九色网站| 国产精品激情av在线播放| 欧美人与性动交| 日韩av第一页| 色爱av美腿丝袜综合粉嫩av| 国产精品免费一区| 中文字幕日韩有码| 久久久视频免费观看| 亚洲国产欧美一区二区丝袜黑人| 国产成人aa精品一区在线播放| 在线看欧美日韩| 欧美激情在线狂野欧美精品| 欧美大成色www永久网站婷| 久久久之久亚州精品露出| 57pao国产成人免费| 久久久女女女女999久久| 久久成人国产精品| 精品国产鲁一鲁一区二区张丽| 亚洲视频网站在线观看| 色妞一区二区三区| 97视频在线观看播放| 97婷婷涩涩精品一区| 成人高清视频观看www| 国产日韩欧美视频| 国产视频亚洲精品| 欧美久久精品一级黑人c片| 国产精品欧美激情| 在线观看欧美www| 奇米4444一区二区三区| 久久精品国亚洲| 国产91|九色| 中文字幕欧美国内| www.99久久热国产日韩欧美.com| 国产成人精品av在线| 欧美精品一区在线播放| 亚洲影视中文字幕| 操日韩av在线电影| 亚洲色图35p|