Java粗淺認識-I/O(三)
阿新 • • 發佈:2018-12-20
Nio2
什麼是Java Nio2,java Nio2是在java 7新增內容,在java1.4 nio的基礎上再次對I/O模型的增強,新增Path類,Files工具類,Paths工具類,主要是為了方便檔案、目錄的操作。
java.nio.file.Path
一個Path代表了一個在本地檔案系統的一個路徑
1.建立一個path類
/** * 建立一個Path類 * * @throws URISyntaxException */ private static void createPath() throws URISyntaxException { //1.根據檔名構建 Path path = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test\\test.txt"); System.out.println(path); //2.根據多個檔名,子檔名構建 Path path1 = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test", "sub", "subTest.txt"); System.out.println(path1); //3.根據統一資源定位符構建 Path path2 = Paths.get(new URI("file:///C:/Users/baopz/Desktop/圖片/test/uri.txt")); System.out.println(path2); //4.根據FileSystems建立 Path path3 = FileSystems.getDefault().getPath("C:", "1.txt"); System.out.println(path3); }
2.Path物件和File相互轉換 Path物件轉換為URI
/** * Path物件和檔案相互轉換 * path轉換為uri */ public static void convert() { //path轉換為檔案 Path path = Paths.get("c://1.txt"); System.out.println(path); File file = path.toFile(); System.out.println(file.getAbsolutePath()); //檔案轉換為path File file1 = new File("C://1.txt"); System.out.println(file1); Path path1 = file1.toPath(); System.out.println(path1); //path轉換為uri URI uri = path1.toUri(); System.out.println(uri); }
3.建立孩子節點,建立兄弟節點
/** * 建立孩子節點,建立兄弟節點 */ public static void resolve() { Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test"); //建立孩子節點 Path child = current.resolve("child"); System.out.println(child); //建立兄弟節點 Path brother = current.resolveSibling("brother"); System.out.println(brother); }
4.得到檔名,以及Path類的計算操作
/**
* path結構,root/0/1/2/..,count不會計算root層,根節點的parent是null
* 擷取部分subPath [start,end),包含start的下標,不包含end的下標
*/
public static void getFilename() {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test\\1.txt");
Path filename = current.getFileName();
System.out.println(filename.toString());
//根據計算得到檔名
filename = current.getName(current.getNameCount() - 1);
System.out.println(filename.toString());
//得到根節點
System.out.println(current.getRoot());
//列印每一層的filename
for (int i = 0; i < current.getNameCount(); i++) {
System.out.println(i + "層 " + current.getName(i));
}
//根節點的父親節點是null
System.out.println(current.getRoot().getParent());
//擷取部分path[start,end)
System.out.println(current.subpath(1,3));
//是不是以1.txt結尾的path,注意這裡不能用來判斷是不是某種格式結尾,這裡計算的最後一個節點
//這裡返回的是true
System.out.println(current.endsWith("1.txt"));
//這裡返回的是false
System.out.println(current.endsWith(".txt"));
}
5.regex或者glob匹配
/**
* regex或者glob匹配
* 匹配語法
* 語法:模式 => {regex|glob}:pattern
*/
public static void match() {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test\\1.txt");
FileSystem fileSystem = FileSystems.getDefault();
//正則表示式匹配.txt結尾
PathMatcher pathMatcher = fileSystem.getPathMatcher("regex:.*.txt");
System.out.println(pathMatcher.matches(current));
//glob匹配.txt結尾
pathMatcher = fileSystem.getPathMatcher("glob:*.txt");
System.out.println(pathMatcher.matches(current));
}
6.java.nio.file.WatchService監控器
這個功能還是非常實用的,檔案監控器,可以監控檔案以及目錄的變化,以及設定監控頻率,這裡是演示,會執行在main執行緒裡面,專案中建議開個執行緒單獨執行,(後面我會吧執行緒的相關操作列出來)。
/**
* 檔案監控器,可以監控檔案以及目錄的變化,以及設定監控頻率
*/
public static void watchServer() throws IOException, InterruptedException {
FileSystem fileSystem = FileSystems.getDefault();
WatchService watchService = fileSystem.newWatchService();
Path path = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test");
//監控事件,新增,修改,刪除,溢位,監控頻率=low
path.register(watchService,new WatchEvent.Kind<?>[]{StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.OVERFLOW},
SensitivityWatchEventModifier.LOW);
while (true) {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> watchEvent : watchKey.pollEvents()) {
//有新檔案建立
if (watchEvent.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
Path path1 = (Path) watchEvent.context();
System.out.println("新建了一個檔案:" + path1);
}
//有檔案被刪除
if(watchEvent.kind()==StandardWatchEventKinds.ENTRY_DELETE){
Path path1 = (Path) watchEvent.context();
System.out.println("刪除了一個檔案:" + path1);
}
if (watchEvent.kind()==StandardWatchEventKinds.ENTRY_MODIFY){
Path path1 = (Path) watchEvent.context();
System.out.println("檔案被修改:"+path1);
}
if (watchEvent.kind()==StandardWatchEventKinds.OVERFLOW){
System.out.println("溢位");
}
}
boolean valid = watchKey.reset();
if (!valid) {
break;
}
}
}
java.nio.file.Files、java.nio.file.FileSystems工具類
1.建立檔案
public static void createFile() throws IOException {
Path path = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test\\test.txt");
//得到上一層節點
Path parent = path.getParent();
if (Files.notExists(parent)) {
Files.createDirectories(parent);
}
//在建立檔案的時候,一定要先存著上一層的目錄
if (Files.notExists(path)) {
Files.createFile(path);
}
}
2.刪除檔案
public static void delete() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test\\1.txt");
boolean isSuccess = Files.deleteIfExists(current);
System.out.println(isSuccess);
}
3.得到BufferedReader,進行字元操作
/**
* 字符集對應不上會拋錯
* @throws IOException
*/
public static void readBuffer() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test\\1.txt");
BufferedReader bufferedReader = Files.newBufferedReader(current, Charset.forName("gbk"));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
}
4.列出當前資料夾下所有檔案
/**
* 列出當前目錄下所有檔案
* @throws IOException
*/
public static void listFile() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test");
DirectoryStream directoryStream = Files.newDirectoryStream(current);
for (Object aDirectoryStream : directoryStream) {
System.out.println(aDirectoryStream);
}
}
5.樹遍歷
public static void walkingTheFileTree() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test");
Set<FileVisitOption> visitOptions = new HashSet<>();
visitOptions.add(FileVisitOption.FOLLOW_LINKS);
//設定開始節點,訪問操作,最大訪問深度,具體訪問操作
Files.walkFileTree(current, visitOptions, 3, new MyFileVisitor());
}
public static class MyFileVisitor implements FileVisitor<Path> {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println("訪問資料夾之前操作。" + dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("訪問當前檔案:" + file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
System.out.println("訪問檔案錯誤:" + file);
//跳過sub
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
System.out.println("訪問資料夾之後操作:" + dir);
return FileVisitResult.CONTINUE;
}
}
6.檔案屬性,以及檔案操作
public static void accessFile() throws IOException {
Path current = Paths.get("C:\\Users\\baopz\\Desktop\\圖片\\test");
FileSystem fileSystem = FileSystems.getDefault();
//遍歷檔案支援的所有檢視
for (String s : fileSystem.supportedFileAttributeViews()) {
System.out.println(s);
}
//basic檢視
BasicFileAttributes basicFileAttributes = Files.readAttributes(current,BasicFileAttributes.class);
System.out.println(basicFileAttributes.lastModifiedTime());
//dos檢視
DosFileAttributes dosFileAttributes = Files.readAttributes(current,DosFileAttributes.class);
System.out.println(dosFileAttributes.isHidden());
//複製
Files.copy(current,current.resolve("副本"));
}
到目前為止,java1.7 的Nio2已經寫完了,接下來會講解關於網路通訊,還有一個非同步通道會在下一章開頭講,會提一下Netty,再之後會針對Netty做專題詳細講解。