Java-AIO

AIO概述

  • AIO(Asynchronous IO)是 Java 1.7之后引入的包. 特点是异步非阻塞, 属 NIO的扩展, 又称 NIO.2
  • AIO采用 Proactor模式, 特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多, 且连接时间较长的应用
  • 主要新增 Path接口, Paths和 Files工具类

Path接口

  • java.nio.file.Path代表一个平台无关的路径, 表示目录结构和指定文件的位置
  • 常用方法:
方法说明
boolean isAbsolute()判断是否为绝对路径
Path getRoot()获取根(ex: C:\)
Path getFileName()获取路径指向的文件或目录的名称
Path getParent()获取父级完整路径(如 Path对象为根, 则返回 null)
int getNameCount()获取根后面路径数量(如指定了文件, 则 +1)
boolean startsWith(Path other)判断是否开头为 other
boolean endsWith(Path other)判断是否结束为 other
URI toUri()获取 URI型式的地址(ex: file:///C:/Users)
Path toAbsolutePath()获取绝对路径(如地址含文件, 则包含文件)
boolean equals(Object other)是否为相同
File toFile()将 Path转为 File类对象

Paths工具类

方法说明
static Path get(String first, String… more)用于将多个字符串串连成 Path路径
static Path get(URI uri)获取指定 uri对应的 Path路径

Files工具类

  • java.nio.file.Files用于操作文件或目录的工具类
  • 常用方法:
方法说明
SeekableByteChannel newByteChannel(Path path, OpenOption… options)获取指定文件的读取和写入通道
DirectoryStream<Path> newDirectoryStream(Path dir)打开 dir对应的目录
Path createDirectory(Path dir, FileAttribute<?>… attrs)创建 dir对应的目录
void delete(Path path)删除 Path对应的文件或目录, 如不存在, 则报错
boolean deleteIfExists(Path path)Path对应的文件或目录存在, 则删除
Path copy(Path source, Path target, CopyOption… options)复制文件 source到 target
Path move(Path source, Path target, CopyOption… options)移动文件 src到 dest
boolean isSameFile(Path path, Path path2)判断两个路径或文件是否相等
boolean isHidden(Path path)判断是否是隐藏文件
String probeContentType(Path path)获取 Path对应的 Content Type; 注: path为目录时, 则返回 null
<V extends FileAttributeView> V getFileAttributeView(Path path, Class<V> type, LinkOption… options)返回给定类型的文件或目录属性视图
<A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption… options)获取 Path对应的文件或目录相关属性
Path setAttribute(Path path, String attribute, Object value, LinkOption… options)给 Path对应的文件或目录, 设置属性(如隐藏属性)
UserPrincipal getOwner(Path path, LinkOption… options)获取文件所有者
Path setOwner(Path path, UserPrincipal owner)设置文件所有者
boolean isSymbolicLink(Path path)判断是否是软链接
boolean isDirectory(Path path, LinkOption… options)判断是否是目录
boolean isRegularFile(Path path, LinkOption… options)判断是否是常规文件(常规文件是永久存储在文件系统中的字节序列, 不是则特殊文件包括符号链接和目录)
FileTime getLastModifiedTime(Path path, LinkOption… options)获取文件的上次修改时间
Path setLastModifiedTime(Path path, FileTime time)修改文件的上次修改时间
long size(Path path)获取 Path对应的文件大小
boolean exists(Path path, LinkOption… options)判断文件是否存在
boolean notExists(Path path, LinkOption… options)判断文件是否不存在
boolean isReadable(Path path)判断文件是否可读
boolean isWritable(Path path)判断文件是否可写
boolean isExecutable(Path path)判断是否是可执行文件
Path walkFileTree(Path start, FileVisitor<? super Path> visitor)遍历文件系统(用于遍历包含子目录的目录)
byte[] readAllBytes(Path path)字节形式读取文件到字节数组(一次性读取其全部内容)
List<String> readAllLines(Path path)字符形式读取文件到列表(一次性读取其全部内容)
Path write(Path path, byte[] bytes, OpenOption… options)写入字节数组到文件
Path write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption… options)写入字符列表到文件(可指定字符编码)
Stream<Path> list(Path dir)遍历文件目录
Stream<Path> walk(Path start, int maxDepth, FileVisitOption… options)遍历目录
Stream<Path> find(Path start, int maxDepth, BiPredicate<Path, BasicFileAttributes> matcher, FileVisitOption… options)遍历目录(需要按文件属性过滤时)
Stream<String> lines(Path path, Charset cs)字符形式读取文件到字符串流(可指定字符编码)
Stream<String> lines(Path path)字符形式读取文件到字符串流

使用例子


	// 获取指定文件的读取和写入通道
	public static void main(String[] args) {
		try (SeekableByteChannel newByteChannel = Files.newByteChannel(
				Paths.get("C:\\Users\\Shawn Jeon\\Pictures\\test\\test2.txt"), StandardOpenOption.READ)
		) {
			// 分配指定大小的缓冲区
			ByteBuffer buf = ByteBuffer.allocate(20);
			int len = 0;
			while ((len = newByteChannel.read(buf)) > 0) {
				// 切换读取模式
				buf.flip();
				// 打印内容
				System.out.print(new String(buf.array(), 0, len));
				// 清空缓冲区
				buf.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 打开 dir对应的目录
	public static void main(String[] args) {
		try (DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(
				Paths.get("C:\\Users\\Shawn Jeon\\Pictures")
			)
		) {
			for (Path path: newDirectoryStream) {
				System.out.println(path);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
//		C:\Users\Shawn Jeon\Pictures\1.jpg
//		C:\Users\Shawn Jeon\Pictures\2.jpg
//		C:\Users\Shawn Jeon\Pictures\Camera Roll
//		C:\Users\Shawn Jeon\Pictures\desktop.ini
//		C:\Users\Shawn Jeon\Pictures\Saved Pictures
//		C:\Users\Shawn Jeon\Pictures\test
	}

	// 创建 dir对应的目录
	public static void main(String[] args) {
		Path dir = Paths.get("C:\\Users\\Shawn Jeon\\Pictures\\test2");
		try {
			Files.createDirectory(dir);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 删除 Path对应的文件或目录, 如不存在, 则报错; 注: 1. 无法删除有内容的目录 2. 无法删除只读文件
	public static void main(String[] args) {
		Path dir = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test");
		try {
			Files.delete(dir);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// Path对应的文件或目录存在, 则删除; 注: 1. 无法删除有内容的目录 2. 无法删除只读文件
	public static void main(String[] args) {
		Path dir = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\새 텍스트 문서.txt");
		try {
			Files.deleteIfExists(dir);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 复制文件 source到 target
	public static void main(String[] args) {
		Path path1 = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\1.txt");
		Path path2 = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\5.txt");
		try {
			// REPLACE_EXISTING: 替换现有文件(如果存在), COPY_ATTRIBUTES: 复制原文件
			Files.copy(path1, path2, StandardCopyOption.COPY_ATTRIBUTES);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 移动文件 src到 dest
	public static void main(String[] args) {
		Path path1 = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\1.txt");
		Path path2 = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\5.txt");
		try {
			// ATOMIC_MOVE: 移动源文件(如果存在, 则替换现有文件)
			Files.move(path1, path2, StandardCopyOption.ATOMIC_MOVE);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 判断两个路径或文件是否相等
	public static void main(String[] args) {
		Path path1 = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\3.txt");
		Path path2 = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\4.txt");
		try {
			if (Files.isSameFile(path1, path2)) {
				System.out.println("相等");
			} else {
				System.out.println("不相等");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 判断是否是隐藏文件
	public static void main(String[] args) {
		Path path = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\5.txt");
		try {
			if (Files.isHidden(path)) {
				System.out.println("是");
			} else {
				System.out.println("否");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 获取 Path对应的 Content Type; 注: path为目录时, 则返回 null
	public static void main(String[] args) {
		Path path = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\4.txt");
		try {
			System.out.println(Files.probeContentType(path)); // text/plain
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		Path file = Paths.get("C:\\Users\\Shawn Jeon\\Pictures");
		// 返回给定类型的文件或目录属性视图
		BasicFileAttributeView bf = Files.getFileAttributeView(file, BasicFileAttributeView.class);
		try {
			// 获取 Path对应的文件或目录相关属性
			BasicFileAttributes attr = bf.readAttributes();
			System.out.println("viewName : " + bf.name());
			System.out.println("creationTime: " + attr.creationTime());
			System.out.println("lastAccessTime: " + attr.lastAccessTime());
			System.out.println("lastModifiedTime: " + attr.lastModifiedTime());
			System.out.println("isDirectory: " + attr.isDirectory());
			System.out.println("isOther: " + attr.isOther());
			System.out.println("isRegularFile: " + attr.isRegularFile());
			System.out.println("isSymbolicLink: " + attr.isSymbolicLink());
			System.out.println("size: " + attr.size());
			long currentTime = System.currentTimeMillis();
			FileTime ft = FileTime.fromMillis(currentTime);
			// @param   lastModifiedTime 修改文件的最后修改时间
			// @param   lastAccessTime 最后查看时间
			// @param   createTime 创建时间
			bf.setTimes(ft, null, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
//		viewName : basic
//		creationTime: 2020-11-11T02:25:30.918661Z
//		lastAccessTime: 2021-02-23T06:06:30.983797Z
//		lastModifiedTime: 2021-02-22T13:59:48.910598Z
//		isDirectory: true
//		isOther: false
//		isRegularFile: false
//		isSymbolicLink: false
//		size: 4096
	}

	// 给 Path对应的文件或目录, 设置属性(如隐藏属性)
	public static void main(String[] args) {
		Path file = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\4.txt");
		try {
			Files.setAttribute(file, "dos:hidden", true);
			// 给文件设置只读属性
			file.toFile().setReadOnly();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// 全局规则 glob:
		//		glob:*.java 匹配以java结尾的文件
		//		glob:*.* 匹配包含'.'的文件
		//		glob:*.{java,class} 匹配以java或class结尾的文件
		//		glob:foo.? 匹配以foo开头且一个字符扩展名的文件
		//		glob:/home/*/* 在unix平台上匹配,例如/home/gus/data等
		//		glob:/home/** 在unix平台上匹配,例如/home/gus,/home/gus/data
		//		glob:c:\\\\* 在windows平台上匹配,例如c:foo,c:bar,注意字符串转义
		// 正则规则 regex:
		//		* 匹配零个或多个字符与名称组件,不跨越目录
		//		** 匹配零个或多个字符与名称组件,跨越目录(含子目录)
		//		? 匹配一个字符的字符与名称组件
		//		\ 转义字符,例如\{表示匹配左花括号
		//		[] 匹配方括号表达式中的范围,连字符(-)可指定范围。例如[ABC]匹配"A"、"B"和"C";[a-z]匹配从"a"到"z";[abce-g]匹配"a"、"b"、"c"、"e"、"f"、"g"
		//		[!...]匹配范围之外的字符与名称组件,例如[!a-c]匹配除"a"、"b"、"c"之外的任意字符
		//		{}匹配组中的任意子模式,多个子模式用","分隔,不能嵌套

		final String pattern = "regex:.*\\.(java|txt)";
		// final String pattern = "glob:**/*.{java,txt}";
		final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(pattern);
		Path path = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test");
		try {
			// 遍历文件系统(用于遍历包含子目录的目录)
			Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
				@Override
				public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
					// 查找java和 txt文件
					if (pathMatcher.matches(file)) {
						System.out.println(file);
						// 找到一个文件, 终止遍历
						// return FileVisitResult.TERMINATE;
					}
					return FileVisitResult.CONTINUE;
				}
			});
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 字符形式读取文件到列表(一次性读取其全部内容)
	public static void main(String[] args) {
		Path file = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\5.txt");
		try {
			List<String> content = Files.readAllLines(file, StandardCharsets.UTF_8);
			System.out.println(content);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 遍历文件目录
	public static void main(String[] args) {
		Path dir = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test");
		try (Stream<Path> stream = Files.list(dir)) {
			stream.forEach(path -> {
				System.out.println(path);
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 字符形式读取文件到字符串流
	public static void main(String[] args) {
		Path file = Paths.get("C:\\Users\\Shawn Jeon\\Downloads\\test\\5.txt");
		try (Stream<String> stream = Files.lines(file, StandardCharsets.UTF_8)) {
			// 打印文件内容行数
			// System.out.println(stream.count());
			stream.forEach(line -> {
				// 遍历内容
				System.out.println(line);
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值