一、NIO
/** * 原始的dump * * @param inputStream * @param outputStream */
public static void dump(InputStream inputStream, OutputStream outputStream) throws IOException {
byte[] data = new byte[1024];
int length;
while ((length = inputStream.read(data)) != -1) {
outputStream.write(data, 0, length);
}
}
/** * 使用 NIO * * @param src * @param dest */
public static void newdump(ReadableByteChannel src, WritableByteChannel dest) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (src.read(buffer) != -1) {
//该方***将limit设置为position的值 而position设置为0
buffer.flip();
dest.write(buffer);
buffer.clear();
}
}
二、NIO2
1. NIO2架构
- 应用程序开发者主要关注java.nio.file, java.nio.file.attribute,文件系统提供者应实现java.nio.file.spi
- NIO2的核心为java.nio.file.spi.FileSystemProvider,本身为抽象类,文件系统提供者应该去实现该类,作用是提供java.nio.file, java.nio.file.attribute的对象实例
- 对于开发者而言,只需要知道FileSystemProvider的存在即可
- 可以使用java.nio.file包中的FileSystems/Paths/Files等类提供的静态方法获取实例即可,比如:
FileSystems.getDefault();
其内部还是会调用FileSystemProvider的方法获取实例
2. 操作路径
public static void main(String[] args) {
//绝对路径
Path p1 = Paths.get("D:\\test");
//相对路径
Path p2 = Paths.get("Desktop\\books");
//拼接多个路径
Path path = Paths.get(System.getProperty("user.home"), "Documents", "Downloads");
String string =
path.toString() + "\n" +
path.getFileName() + "\n" +
path.getName(0) + "\n" +
path.getNameCount() + "\n" +
path.subpath(0, 2) + "\n" +
path.getParent() + "\n" +
path.getRoot();
System.out.println(string);
//移除冗余信息
path.normalize();
//相对路径转绝对路径 有冗余信息会移除
path.toAbsolutePath();
//切换路径
p1.relativize(p2);
//比较两个路径是否相同
p1.equals(p2);
//比较路径起始是否相同
p1.startsWith(p2);
//比较路径结尾是否相同
p1.endsWith(p2);
}
//输出
C:\Users\24234\Documents\Downloads
Downloads
Users
4
Users\24234
C:\Users\24234\Documents
C:\
3. 属性读取与设定
public static void main(String[] args) throws IOException {
Path paths = Paths.get("E:\\MYLOG_1.log");
BasicFileAttributes attributes = Files.readAttributes(paths, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
System.out.println(attributes.creationTime());
System.out.println(attributes.lastAccessTime());
System.out.println(attributes.lastModifiedTime());
System.out.println(attributes.isDirectory());
FileSystem fileSystem = FileSystems.getDefault();
for (FileStore fileStore : fileSystem.getFileStores()) {
System.out.print(fileStore.toString() + "-" + fileStore.getTotalSpace() + "-");
System.out.println(fileStore.getUsableSpace());
}
}
//输出
2019-03-07T08:33:50.409467Z
2019-05-29T08:23:06.064721Z
2019-03-07T08:33:50.696443Z
false
Windows (C:)-126485602304-21558349824
Leo-D (D:)-446347341824-398526582784
Leo-E (E:)-446346293248-406314741760
(F:)-106966286336-67977740288
4. 操作文档与记录
public static void main(String[] args) throws IOException {
Path paths = Paths.get("E:\\MYLOG_1.log");
//删除文件 文件不存在则抛出NoSuchFileException
Files.delete(paths);
//在文档不存在时调用,并不会抛出异常
Files.deleteIfExists(paths);
Path p1 = Paths.get("");
Path p2 = Paths.get("");
//StandardCopyOption.REPLACE_EXISTING目标存在则会覆盖
//StandardCopyOption.COPY_ATTRIBUTES会尝试覆盖相关属性
//LinkOption.NOFOLLOW_LINKS 则不会跟随符号链接
Files.copy(p1, p2, StandardCopyOption.REPLACE_EXISTING);
//如果文件系统支持原子移动,可在移动时指定StandardCopyOption.ATOMIC_MOVE
Files.move(p1, p2, StandardCopyOption.ATOMIC_MOVE);
}
5. 读取/访问目录
public static void main(String[] args) throws IOException {
Iterable<Path> rootDirectories = FileSystems.getDefault().getRootDirectories();
rootDirectories.forEach(System.out::println);
}
//输出
C:\
D:\
E:\
F:\
6. 过滤/搜索文档
Glob语法比正则表达式(regex)简单,可以用于字符串匹配