一、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)简单,可以用于字符串匹配