从Java1.0到1.3,我们在开发需要I/O支持的应用时,要面临以下问题:

  • 没有数据缓冲区或通道的概念,开发人员要编程处理很多底层细节
  • I/O操作会被阻塞,扩展能力有限
  • 所支持的字符集编码有限,需要进行很多手工编码工作来支持特定类型的硬件。
  • 不支持正则表达式,数据处理困难。

为了解决这些问题,在Java1.4引入了NIO。其中有两次主要改进:

  • 在Java1.4中引入非阻塞I/O
  • 在Java7中对非阻塞I/O进行修改

自此Java为I/O操作抽象出了缓冲区和通道区;字符集的编码和解码能力;提供了能够将文件映射为内存数据的接口;实现非阻塞I/O的能力;基于流行的Perl实现的正则表达式类库。

NIO使Java向前迈出了一大步,但I/O编程对于开发人员来说仍然是个挑战,特别是对于文件和目录而言,支持力度还是不够。为了突破这些局限性,在Java7中提供了NIO.2 API。它有三个目标:

  • 一个能批量获取文件属性的文件系统接口,引入标准文件系统实现的服务提供者接口
  • 提供一个套接字和文件都能够进行异步
  • 完成JSR-51中定义的套接字--通道功能,包括额外对绑定、选项配置和多播数据报的支持。

Path:通常代表文件系统中的位置。

  1. 创建一个Path

    Path path1 = Paths.get("D:\\test\\test1"); // 等同 Path path1 = FileSystems.getDefault().getPath("D:\\test");
  2. 从Path中获取信息

    我们可以从Path中获取信息,比如其父目录,文件名等...

    System.out.println("fileName : " + path1.getFileName()); // 获取文件名称
    System.out.println("number of name elements : " + path1.getNameCount()); // 获取名称元素的数量
    System.out.println("parent path : " + path1.getParent());
    System.out.println("root of path : " + path1.getRoot());
    System.out.println("subpath from root, 2 elements deep : " + path1.subpath(0, 2)); // 获取第0-2个元素之间的子路径
  3. NIO.2 Path和Java已有的FIle类

    新API中的类可以完全替代过去基于java.io.File的API。但是我们不可避免的要和大量遗留下来的I/O代码交互。Java7提供了两个新方法:

    • java.io.File类中新增了toPath()方法,可以把已有的File转化为新的Path
    • Path类有个toFile()方法,它可以把已有的Path转为File
    File file = new File("D:\\test");
    Path path3 = file.toPath(); // file to path
    path3.toAbsolutePath();
    file = path3.toFile(); // path to file
  4. 在目录中查找文件

    先来一个简单的例子,用匹配模式过滤出当前目录下所有的.txt和.jpg文件。这是处理单个目录的能力。

    Path path4 = Paths.get("D:\\test");
    
    DirectoryStream<Path> stream = Files.newDirectoryStream(path4, "*.{txt,jpg}"); // 声明过滤流,匹配模式为glob模式匹配
    for (Path entry : stream) {
    System.out.println(entry.getFileName());
    }
  5. 遍历目录树

    Java7支持整个目录树的遍历。也就是说我们可以很容易的搜索目录树中的文件,在子目录中查找,并对它们执行操作。

    Path path5 = Paths.get("F:\\test\\demo"); // 设置起始目录
    Files.walkFileTree(path5, new FindJavaVisitor()); // 关键方法 private static class FindJavaVisitor extends SimpleFileVisitor<Path> {
    // SimpleFileVisitor可以完成大部分工作,比如遍历目录。我们唯一要做的就是重写visitFile()这个方法。
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
    if (file.toString().endsWith(".java")) {
    System.out.println(file.getFileName());
    }
    return FileVisitResult.CONTINUE;
    }
    }

Files:让我们轻松复制,移动,删除或处理文件的工具类,有我们需要的所有方法。

  1. 创建和删除文件

    Path path6 = Paths.get("D:\\backup\\test.txt");
    Files.createFile(path6); // 创建文件,要保证D:\\backup存在
    Files.delete(path6);
  2. 文件的复制和移动

    Path sourcePath7 = Paths.get("D:\\test\\test.txt");
    Path targetPath7 = Paths.get("D:\\backup\\test.txt");
    Files.copy(sourcePath7, targetPath7, StandardCopyOption.REPLACE_EXISTING); // REPLACE_EXISTING 覆盖即替换已有文件
    Files.move(sourcePath7, targetPath7, StandardCopyOption.REPLACE_EXISTING);
  3. 文件的属性

    Path path8 = Paths.get("D:\\test");
    System.out.println(Files.getLastModifiedTime(path8));
    System.out.println(Files.size(path8));
    System.out.println(Files.isSymbolicLink(path8));
    System.out.println(Files.isDirectory(path8));
    System.out.println(Files.readAttributes(path8, "*")); // 获取文件所有的属性
  4. 快速读写数据

    Java7可以尽可能多的提供用来的读取和写入文件内容的辅助方法。

    当然这些新方法使用Path,但它们也可以与那些java.io包里基于流的类进行互相操作。因此我们用一个方法就可以读取文件中的所有行或全部字节。

    // Java7可以直接用缓冲区的读取器和写入器或输入输出流(为了和以前的Java I/O代码兼容)打开文件。
    BufferedWriter writer = Files.newBufferedWriter(path9, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
    writer.write("Hello world...");
    writer.flush();
    writer.close(); BufferedReader reader = Files.newBufferedReader(path9, StandardCharsets.UTF_8);
    String line;
    while ((line = reader.readLine()) != null) {
    System.out.println(line);
    } // 简化读取和写入 List<String> lines = Files.readAllLines(path9, StandardCharsets.UTF_8);
    for (String line1 : lines) {
    System.out.println(line1);
    } byte[] bytes = Files.readAllBytes(path9); // 读取文件字节流
    System.out.println(new String(bytes, StandardCharsets.UTF_8)); Files.write(path9, bytes); // 写入文件字节流

    以前读写文件都比较麻烦,用Java7的NIO之后是不是非常方便呢?

参考内容:《Java程序员修炼之道》

【Java基础 】Java7 NIO Files,Path 操作文件的更多相关文章

  1. Java基础之NIO

    NIO简介: Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同 ...

  2. Java 7 中 NIO.2 的使用——文件递归操作

    众所周知,递归编程是一项有争议的技术,因为它需要大量的内存,但是它能简化一些编程任务.基本上,一个递归操作都是程序调用自己传递参数修改的值或者参数传递到当前的程序循环中.递归编程通常用来计算阶乘斐波那 ...

  3. Java基础——环境变量(PATH)和类变量(CLASSPATH)

    一.环境变量(PATH) 科普下,环境变量不是java的知识,是windows系统的环境变量. 下面请看怎么查看和修改windows的环境变量 在“我的电脑”右键属性进入后 点击“高级系统设置”(如下 ...

  4. 使用Java内存映射(Memory-Mapped Files)处理大文件

    >>NIO中的内存映射 (1)什么是内存映射文件内存映射文件,是由一个文件到一块内存的映射,可以理解为将一个文件映射到进程地址,然后可以通过操作内存来访问文件数据.说白了就是使用虚拟内存将 ...

  5. Java基础教程:IO流与文件基础

    Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列的对象 ...

  6. java基础 File与递归练习 使用文件过滤器筛选将指定文件夹下的小于200K的小文件获取并打印按层次打印(包括所有子文件夹的文件) 多层文件夹情况统计文件和文件夹的数量 统计已知类型的数量 未知类型的数量

    package com.swift.kuozhan; import java.io.File; import java.io.FileFilter; /*使用文件过滤器筛选将指定文件夹下的小于200K ...

  7. java基础知识3--如何获取资源文件(Java中获取资源文件的url)

    java开发中,常见的resource文件有:.xml,.properties,.txt文件等,后台开发中经常用到读取资源文件,处理业务逻辑,然后返回结果. 获取资源文件的方法说明getResourc ...

  8. Python学习笔记(15)- os\os.path 操作文件

    程序1 编写一个程序,统计当前目录下每个文件类型的文件数,程序实现如图: import os def countfile(path): dict1 = {} # 定义一个字典 all_files = ...

  9. Java 基础-IO、stream 流、文件操作

    输入输出流的分类 在 java.io 包中,包含了输入输出操作所需的类. I/O 流可以安装不同的标准分类: 按照流的方向分类: 输入流:将信息从代码外部输入代码 输出流:将代码得到的数据输出到文件. ...

随机推荐

  1. MongoDB学习总结(六) —— 数据库备份和恢复

    我们都知道数据库数据经常备份是多么的重要,MongoDB作为一个数据库系统,自然提供了完善,丰富而且好用的备份与恢复机制. 以下介绍三种数据库备份和恢复的方式 > 数据目录直接拷贝 数据库目录直 ...

  2. C#类详解

    类: 类是一种数据结构,它可以包含数据成员(常数和字段).函数成员(方法.属性.事件.索引器.运算符实例.构造函数静态构造函数和析构函数),以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类可以 ...

  3. plupload插件的错误SCRIPT601

    在网上copy 别人的demo来用结果发生这个问题.浪费半天时间才找到问题. 在IE8下下提示这个异常. SCRIPT601: 未知的运行时错误plupload.full.min.js, 行15 字符 ...

  4. Android Weekly Notes Issue #245

    Android Weekly Issue #245 February 19th, 2017 Android Weekly Issue #245 本期内容: 写好单元测试的几条原则; 如何mock Ko ...

  5. BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)

    这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= = 岛娘真是太厉害了,先丢链接:http://www.shuizilo ...

  6. 2013~2014年度 NOIP~GDOI总结

    滚回去撸一年中考撸完之后就迎来了NOIP2013(话说初赛差点被坑了有木有= =)想想当年10月还是那样的天真的去了广州,结果就被虐成翔的回来了= =只做了三道签到题的渣渣就是弱= =DAY1T2死活 ...

  7. linux oracle 10g 安装时 .bash_profile的设置

    export ORACLE_BASE=/home/oracle/oracle10g export ORACLE_SID=ccpbs export ORACLE_HOME=$ORACLE_BASE/pr ...

  8. 从Angular2路由引发的前后端路由浅谈

    笔者的学习进度比较慢,直到两年以前写的网站都还是以服务端为主导的,即网站的所有视图都由服务器视图模板来渲染,笔者使用的是 DotNet MVC,开发套路就是在Controller里面写Action,在 ...

  9. 规范 : angular 组合 jquery plugin

    jquery 会有document.ready ,这是会把model value 给 set 去 jquery ,如果set 不进,可能需要整个渲染(refresh).在操作时需要找到接口,在找到va ...

  10. 【java基础之jdk源码】集合类

    最近在整理JAVA 基础知识,从jdk源码入手,今天就jdk中 java.util包下集合类进行理解 先看图 从类图结构可以了解 java.util包下的2个大类: 1.Collecton:可以理解为 ...