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

首頁 > 開發 > Java > 正文

Java NIO Path接口和Files類配合操作文件的實例

2024-07-13 10:13:39
字體:
來源:轉載
供稿:網友

Path接口

1、Path表示的是一個目錄名序列,其后還可以跟著一個文件名,路徑中第一個部件是根部件時就是絕對路徑,例如 / 或 C:/ ,而允許訪問的根部件取決于文件系統;

2、以根部件開始的路徑是絕對路徑,否則就是相對路徑;

3、靜態的Paths.get方法接受一個或多個字符串,字符串之間自動使用默認文件系統的路徑分隔符連接起來(Unix是 /,Windows是 / ),這就解決了跨平臺的問題,接著解析連接起來的結果,如果不是合法路徑就拋出InvalidPathException異常,否則就返回一個Path對象;

//假設是Unix的文件系統 Path absolute = Paths.get("/home", "cat"); //絕對路徑  Path relative = Pahts.get("ixenos", "config", "user.properties"); //相對路徑

4、由String路徑獲取Path對象

get還可以獲取一整條路徑(即多個部件構成的單個字符串),例如從配置文件中讀取路徑:

String baseDir = properties.getProperty("base.dir"); //可能獲得 /opt/ixenos 或者 C:/Program Files/ixenos Path basePath = Paths.get(baseDir);

5、組合或解析路徑

1) 調用 p.resolve(q) 將按下面的規則返回一個Path:如果q是絕對路徑,則返回q,否則追加路徑返回 p/q 或者 p/q

Path workRelative = Paths.get("work");Path workPath = basePath.resolve(workRelative); //resolve也可以接受字符串形參Path workPath = basePath.resolve("work");

2) 調用 p.resolveSibling("q") 將解析指定路徑 p 的父路徑 o ,并產生兄弟路徑 o/q

 Path tempPath = workPath.resolveSibling("temp"); /* 如果workPath是 /opt/ixenos/work 那么將創建 /opt/ixenos/temp  */

3) 調用 p.relativize(r) 將產生一個冗余路徑q,對q進行解析將產生相對路徑r,最終r不包含和p的交集路徑

/* pathA為 /home/misty pathB為 /home/ixenos/config  現已pathA對pathB進行相對化操作,將產生冗余路徑*/Path pathC = pathA.relativize(pathB); //此時pathC為 ../ixenos/config/* normalize方法將移除冗余部件*/Path pathD = pathC.normalize(); //pathD為 /ixenos/config

4) toAbsolutePath 將產生給定路徑的絕對路徑,從根部件開始

5) Path類還有一些有用的斷開和組合路徑的方法,比如 getParent、getFileName、getRoot//獲得根目錄

6) Path有個toFile方法用來跟遺留類File類打交道,File類也有個toPath方法

Files工具類

1、讀寫文件

方法簽名:

static path write(Path path, byte[] bytes, OpenOption... options)

static path write(Path path, Iterable<? extends CharSequence> lines, OpenOption... options)

這里只列舉下面用到的方法,更多方法請看API文檔...

其中OpenOption是個nio接口,StandardOpenOption是其枚舉實現類,各枚舉實例功能請查看API文檔

/* Files提供的簡便方法適用于處理中等長度的文本文件 如果要處理的文件長度較大,或者二進制文件,那么還是應該使用經典的IO流 *///將文件所有內容讀入byte數組中byte[] bytes = Files.readAllBytes(path); //傳入Path對象//之后可以根據字符集構建字符串String content = new String(bytes, charset);//也可以直接當作行序列讀入List<String> lines = Files.readAllLines(path, charset);//相反,也可以寫一個字符串到文件中,默認是覆蓋Files.write(path, content.getBytes(charset)); //傳入byte[]//追加內容,根據參數決定追加等功能Files.write(path, content.getBytes(charset), StandardOpenOption.APPEND); //傳入枚舉對象,打開追加開關//將一個行String的集合List寫出到文件中Files.write(path, lines);

2、復制、剪切、刪除

方法簽名:

static path copy(Path source, Path target, CopyOption... options)

static path move(Path source, Path target, CopyOption... options)

static void delete(Path path) //如果path不存在文件將拋出異常,此時調用下面的比較好

static boolean deleteIfExists(Path path)

這里只列舉下面用到的方法,更多方法請看API文檔...

其中CopyOption是個nio接口,StandardCopyOption是其枚舉實現類,各枚舉實例功能請查看API文檔

其中有個ATOMIC_MOVE可以填入用來保證原子性操作,要么移動成功完成,要么源文件保持在原位置

//復制Files.copy(fromPath, toPath);//剪切Files.move(fromPath, toPath);/* 以上如果toPath已存在,那么操作失敗, 如果要覆蓋,需傳入參數REPLACE_EXISTING 還要復制文件屬性,傳入COPY_ATTRIBUTES*/Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);

3、創建文件和目錄

//創建新目錄,除了最后一個部件,其他必須是已存在的Files.createDirectory(path); //創建路徑中的中間目錄,能創建不存在的中間部件Files.createDirectories(path);/* 創建一個空文件,檢查文件存在,如果已存在則拋出異常 而檢查文件存在是原子性的,因此在此過程中無法執行文件創建操作*/Files.createFile(path);//添加前/后綴創建臨時文件或臨時目錄Path newPath = Files.createTempFile(dir, prefix, suffix);Path newPath = Files.createTempDirectory(dir, prefix);

4、獲取文件信息

略,具體看API文檔,或者corejava page51

5、迭代目錄中的文件

舊的File類有兩個方法獲取目錄中所有文件構成的字符串數組,String[] list() 和String[] list(FileFilter filter),但是當目錄中包含大量文件時,這兩方法性能會非常低。

原因分析:

1、//File類list所有文件 public String[] list() {  SecurityManager security = System.getSecurityManager(); //文件系統權限獲取  if (security != null) {   security.checkRead(path);  }  if (isInvalid()) {   return null;  }  return fs.list(this); //底層調用FileSystem的list } //FileSystem抽象類的list //File類中定義fs是由DefaultFileSystem靜態生成的private static final FileSystem fs = DefaultFileSystem.getFileSystem();//因此我們來看一下DefaultFileSystem類,發現是生成一個WinNtFileSystem對象class DefaultFileSystem { /**  * Return the FileSystem object for Windows platform.  */ public static FileSystem getFileSystem() {  return new WinNTFileSystem(); }}//而WinNtFileSystem類繼承于FileSystem抽象類,這里我們主要觀察它的list(File file)方法 @Overridepublic native String[] list(File f);/*我們可以看到這是個native方法,說明list的操作是由操作系統的文件系統控制的,當目錄中包含大量的文件時,這個方法的性能將會非常低。由此為了替代,NIO的Files類設計了newDirectoryStream(Path dir)及其重載方法,將生成Iterable對象(可用foreach迭代)*///~ 2、//回調過濾 public String[] list(FilenameFilter filter) { //采用接口回調  String names[] = list(); //調用list所有  if ((names == null) || (filter == null)) {   return names;  }  List<String> v = new ArrayList<>();  for (int i = 0 ; i < names.length ; i++) {   if (filter.accept(this, names[i])) { //回調FilenameFileter對象的accept方法    v.add(names[i]);   }  }  return v.toArray(new String[v.size()]); }

這時候高科技來了——Files獲得可迭代的目錄流,

傳入一個目錄Path,遍歷子孫目錄返回一個目錄Path的Stream,注意這里所有涉及的Path都是目錄而不是文件!

因此,Files類設計了newDirectoryStream(Path dir)及其重載方法,將生成Iterable對象(可用foreach迭代)

遍歷目錄得到一個可迭代的子孫文件集合

 

staticDirectoryStream<Path> newDirectoryStream(Path dir)
Opens a directory, returning a DirectoryStream to iterate over all entries in the directory.
staticDirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter)
Opens a directory, returning a DirectoryStream to iterate over the entries in the directory.
staticDirectoryStream<Path> newDirectoryStream(Path dir, String glob)

 

返回一個 目錄流 ,可以看成一個存放著全部Path的實現了Iterable的集合,

因此可用迭代器或foreach迭代,只是使用迭代器的時候要注意不能invoke另一個Iterator:

While DirectoryStream extends Iterable, it is not a general-purpose Iterable as it supports only a single Iterator; invoking the iterator method to obtain a second or subsequent iterator throws IllegalStateException.

示例:

try(DirectoryStream<Path> entries = Files.newDirectoryStream(dir)){ for(Path entry : entries) {   ... }}

可以傳入glob參數,即使用glob模式來過濾文件(以取代list(FileFilter filter)):

newDirectoryStream(Path dir, String glob) 注意是String類型

try(DirectoryStream<Path> entries = Files.newDirectoryStream(dir, "*.java")) // {  ... }

glob模式

所謂的 glob 模式是指 shell 所使用的簡化了的正則表達式。

1.星號 * 匹配路徑組成部分0個或多個字符;例如 *.java 匹配當前目錄中的所有Java文件

2.兩星號 ** 匹配跨目錄邊界0個或多個字符;例如 **.java 匹配在所有子目錄中的Java文件

3.問號(?)只匹配一個字符;例如 ????.java 匹配所有四個字符的Java文件,不包括擴展名;使用?是因為*是通配符不指定數量

4.[...] 匹配一個字符集合,可以用連線 [0-9] 和取反符 [!0-9];例如 Test[0-9A-F].java 匹配Testx.java,假設x是一個十六進制數字,[0-9A-F]是匹配單個字符為十六進制數字,比如B(十六進制不區分大小寫)

如果在方括號中使用短劃線分隔兩個字符,表示所有在這兩個字符范圍內的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的數字)。

5.{...} 匹配由逗號隔開的多個可選項之中的一個;例如 *.{java,class} 匹配所有Java文件和類class文件

6./ 轉義上述任意模式中的字符;例如 */** 匹配所有子目錄中文件名包含*的文件,這里為 ** 轉義,前面是匹配0個或多個字符

下面是網友總結的Glob模式:

 

Glob模式 描述
*.txt 匹配所有擴展名為.txt的文件
*.{html,htm} 匹配所有擴展名為.html或.htm的文件。{ }用于組模式,它使用逗號分隔
?.txt 匹配任何單個字符做文件名且擴展名為.txt的文件
. 匹配所有含擴展名的文件
C:/Users/* 匹配所有在C盤Users目錄下的文件。反斜線“/”用于對緊跟的字符進行轉義
/home/** UNIX平臺上匹配所有/home目錄及子目錄下的文件。**用于匹配當前目錄及其所有子目錄
[xyz].txt 匹配所有單個字符作為文件名,且單個字符只含“x”或“y”或“z”三種之一,且擴展名為.txt的文件。方括號[]用于指定一個集合
[a-c].txt 匹配所有單個字符作為文件名,且單個字符只含“a”或“b”或“c”三種之一,且擴展名為.txt的文件。減號“-”用于指定一個范圍,且只能用在方括號[]內
[!a].txt 匹配所有單個字符作為文件名,且單個字符不能包含字母“a”,且擴展名為.txt的文件。嘆號“!”用于否定

 

遍歷得到某個目錄的所有子孫文件集合再迭代不夠爽?來,我們來直接遍歷某個目錄的所有子孫成員(包括目錄和文件)

我們可以調用Files類的walkFileTree方法,并傳入一個FileVisitor接口類型的對象(還有更多方法在API里等你發現……)

/*傳入一個FileVisitor子類的匿名對象*/Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {   //walkFileTree回調此方法來遍歷所有子孫   public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException   {    if(attrs.isDirectory()) //自定義的選擇,屬于業務代碼,這和walkFileTree的宗旨(遍歷所有子孫成員)無關     System.out.println(path);    return FileVisitResult.CONTINUE;   }   public FileVisitResult visitFileFailed(Path path, IOException exc) throws IOException   {    return FileVisitResult.CONTINUE;   } });

咱們來總結一下,

Files.newDirectoryStream(Path dir) 遍歷后返回一個可迭代的子孫文件集合;

Files.walkFileTree(Path dir, FileVisitor fv) 是一個遍歷子孫目錄和文件的過程;

ZIP文件系統

由上文知道,Paths類會在默認的文件系統中查找路徑,即在用戶本地磁盤中的文件。

其實,我們也可以有其他的文件系統,比如ZIP文件系統。

/*假設zipname是某個ZIP文件的名字*/FileSystem fs = FileSystems.newFileSystem(Paths.get(zipname), null);

上述代碼將建立一個基于zipname的文件系統,它包含ZIP文檔中的所有文件。

1)如果知道文件名(String類型),那么從這個ZIP文檔中復制出這個文件就很容易:

Files.copy(fs.getPath(fileName), targetPath);

Q:fs.getPath是使用了ZIP文件系統來getPath,那么默認的文件系統能調用嗎?

A:能。FileSystem類中有一個靜態的getDefault()方法,返回一個默認的文件系統對象,同樣可以由文件名getPath。

具體getPath(String name)是遍歷還是隨機訪問,有空再去看源碼實現。

2)要列出ZIP文檔中的所有文件,同樣可以用walkFileTree遍歷文件樹

FileSystem fs = FileSystems.newFileSystem(Paths.get(fileName), null);//walkFileTree需要傳入一個要被遍歷的目錄Path,和一個FileVisitor對象Files.walkFileTree(fs.getPath("/"),   newSimpleFileVisitor<Path>(){    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws Exception{      System.out.println(file);      return FileVisitResult.CONTINUE;   });

以上這篇Java NIO Path接口和Files類配合操作文件的實例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美成人免费全部| 欧美激情精品久久久久| 久久久精品中文字幕| 色噜噜国产精品视频一区二区| 高清欧美电影在线| 欧美综合在线第二页| 日韩一级裸体免费视频| 日本久久久久亚洲中字幕| 欧美在线一区二区视频| 91中文字幕一区| 欧美一区二粉嫩精品国产一线天| 日本不卡视频在线播放| 26uuu另类亚洲欧美日本老年| 91国在线精品国内播放| 亚洲欧美在线一区二区| 日韩av影视综合网| 日韩欧美亚洲综合| 日韩av在线影视| 午夜精品一区二区三区视频免费看| 亚洲国产成人精品电影| 国产精品一区二区三区免费视频| 欧美亚洲激情视频| 91大神在线播放精品| 国产精品69精品一区二区三区| 亚洲午夜未满十八勿入免费观看全集| 91精品国产综合久久香蕉的用户体验| 久久综合免费视频| 亚洲成人久久电影| 91影视免费在线观看| 国产日本欧美一区二区三区在线| 国产亚洲精品久久久久动| 综合网中文字幕| 成人免费高清完整版在线观看| 成人欧美一区二区三区在线湿哒哒| 欧美午夜精品伦理| 国产精品xxxxx| 欧美性猛交xxxxx免费看| 九九热r在线视频精品| 欧美午夜丰满在线18影院| 亚洲欧洲成视频免费观看| 欧美影院久久久| 久久久精品一区二区三区| 欧美激情综合亚洲一二区| 最新国产成人av网站网址麻豆| 欧美亚洲激情视频| 久久中文字幕视频| 日韩av在线免费看| **欧美日韩vr在线| 国产欧美日韩高清| 国产美女高潮久久白浆| 5252色成人免费视频| 色噜噜亚洲精品中文字幕| 欧美做爰性生交视频| 日本久久中文字幕| 中文字幕一区日韩电影| 日本精品久久中文字幕佐佐木| 欧美大片免费观看在线观看网站推荐| 国产精品视频公开费视频| 国产精品久久99久久| 2019亚洲日韩新视频| 青青草99啪国产免费| 亚洲a级在线播放观看| 国产精品入口日韩视频大尺度| 国产精品网红福利| 欧美洲成人男女午夜视频| 国产在线98福利播放视频| 亚洲淫片在线视频| 久久精品国产一区二区三区| 亚洲免费一级电影| 亚洲精品动漫久久久久| 中文字幕精品国产| 青青在线视频一区二区三区| 国产日韩欧美在线观看| 欧美日韩精品中文字幕| 91视频-88av| 中文字幕日韩综合av| 97视频在线观看免费高清完整版在线观看| 日韩欧亚中文在线| 欧美一级淫片videoshd| 亚洲黄色在线观看| 一夜七次郎国产精品亚洲| 欧美人交a欧美精品| 亚洲国产精品推荐| 综合欧美国产视频二区| 欧美日韩激情视频| 欧美日韩另类视频| 国产一区二区日韩| 国产精品影院在线观看| 国产九九精品视频| 成人免费大片黄在线播放| 亚洲一区二区三区四区视频| 一本色道久久综合狠狠躁篇怎么玩| 成人免费午夜电影| 日韩女在线观看| 欧美在线视频在线播放完整版免费观看| 国产女精品视频网站免费| 91精品国产成人| 亚洲精品一区二区三区婷婷月| 亚洲夜晚福利在线观看| 久久精品中文字幕免费mv| 青青青国产精品一区二区| 国产精国产精品| 欧美色xxxx| 精品视频久久久久久| 亚洲欧洲中文天堂| 国产精品久久久久av| 国产99视频精品免视看7| 国产在线精品成人一区二区三区| 26uuu久久噜噜噜噜| 国产精品免费网站| 亚洲欧美第一页| 日韩中文有码在线视频| 精品亚洲精品福利线在观看| 韩国视频理论视频久久| 午夜精品一区二区三区在线播放| 9.1国产丝袜在线观看| 精品国内亚洲在观看18黄| 91精品视频在线播放| 精品福利免费观看| 亚洲有声小说3d| 久久久www成人免费精品张筱雨| 日韩在线视频线视频免费网站| 欧美人成在线视频| 日韩中文字幕精品视频| 在线日韩精品视频| 欧美xxxx综合视频| 亚洲自拍欧美色图| 欧美激情亚洲视频| 午夜精品福利电影| 在线观看欧美视频| 一本久久综合亚洲鲁鲁| 精品偷拍各种wc美女嘘嘘| 久久影院在线观看| 国模视频一区二区| 欧美激情网友自拍| 亚洲色图第三页| 热久久视久久精品18亚洲精品| 欧美精品videosex牲欧美| 国产精品毛片a∨一区二区三区|国| 日韩一区二区福利| 亚洲精品按摩视频| 成人国内精品久久久久一区| 日韩中文视频免费在线观看| 日韩一区二区久久久| 久久久国产精彩视频美女艺术照福利| 这里只有精品丝袜| 亚洲成人教育av| 欧美激情精品久久久久久久变态| 日韩欧美视频一区二区三区| 日韩欧美国产高清91| 亚洲第一在线视频| 在线视频免费一区二区| 亚洲人成网在线播放| 欧美国产乱视频| 成人免费视频a| 国产欧美一区二区三区视频| 精品久久香蕉国产线看观看亚洲| 国产精品自拍偷拍视频| 欧美日韩日本国产| 亚洲美女黄色片| 久久噜噜噜精品国产亚洲综合| 亚洲在线免费看| 国产日韩精品综合网站| 欧洲午夜精品久久久|