javajavase

NIO

Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。

  1. Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO
  2. |-----java.nio.channels.Channel
  3. |---- FileChannel:处理本地文件
  4. |---- SocketChannelTCP网络编程的客户端的Channel
  5. |---- ServerSocketChannelTCP网络编程的服务器端的Channel
  6. |---- DatagramChannelUDP网络编程中发送端和接收端的Channel

NIO.2
随着JDK1.7的发布,Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为NIO.2。因为NIO提供的一些功能,NIO已经成为文件处理中越来越重要的部分

Path、Paths、Files —-JDK 7.0提供

早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,所提供的方法性能也不高。而且,大多数方法在出错时仅返回失败,并不会提供异常信息
NIO.2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。Path可以看成是File类的升级版本,实际引用的资源也可以不存在

  • 在以前IO操作都是这样写的
    • import java.io.File
    • File file = new File(“index.html”);
  • 但在Java7中,我们可以这样写:
    • import java.nio.file.Path;
    • import java.nio.file.Paths;
    • Path path = Paths.get(“index. html”);
  • 同时,NIO.2在java.nio.file包下还提供了Files、Paths工具类,Files包含了大量静态的工具方法来操作文件;Paths则包含了两个返回Path的静态工厂方法

Paths的使用

  • Paths类提供的静态get()方法用来获取Path对象
  • **static Path get(String first, String... more)**用于将多个字符串串连成路径
  • **static Path get(URI uri)**返回指定uri对应的Path路径

    1. // 如何使用Paths实例化Path
    2. @Test
    3. public void test1() {
    4. // new File(String filepath)
    5. // new File(String parent,String filename);
    6. Path path1 = Paths.get("d:\\nio\\hello.txt");
    7. Path path2 = Paths.get("d:\\", "nio\\hello.txt");
    8. System.out.println(path1);
    9. System.out.println(path2);
    10. Path path3 = Paths.get("d:\\", "nio");
    11. System.out.println(path3);
    12. }

    常用方法
    **String toString()**返回调用Path对象的字符串表示形式
    **boolean startsWith(String path)**判断是否以path路径开始
    **boolean endsWith(String path)**判断是否以path路径结束
    **boolean isAbsolute()**判断是否是绝对路径
    **Path getParent()**返回Path对象包含整个路径,不包含Path对象指定的文件路径
    **Path getRoot()**返回调用Path对象的根路径
    **Path getFileName()**返回与调用Path对象关联的文件名
    **int getNameCount()**返回Path根目录后面元素的数量
    **Path getName(int idx)**返回指定索引位置idx的路径名称
    **Path toAbsolutePath()**作为绝对路径返回调用Path对象
    **Path resolve(Path p)**合并两个路径,返回合并后的路径对应的Path对象
    **File toFile()**将Path转化为File类的对象 ```java // Path中的常用方法 @Test public void test2() { Path path1 = Paths.get(“d:\“, “nio\nio1\nio2\hello.txt”); Path path2 = Paths.get(“hello.txt”);

    // String toString() : 返回调用 Path 对象的字符串表示形式 System.out.println(path1);

    // boolean startsWith(String path) : 判断是否以 path 路径开始 System.out.println(path1.startsWith(“d:\nio”)); // boolean endsWith(String path) : 判断是否以 path 路径结束 System.out.println(path1.endsWith(“hello.txt”)); // boolean isAbsolute() : 判断是否是绝对路径 System.out.println(path1.isAbsolute() + “~”); System.out.println(path2.isAbsolute() + “~”); // Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径 System.out.println(path1.getParent()); System.out.println(path2.getParent()); // Path getRoot() :返回调用 Path 对象的根路径 System.out.println(path1.getRoot()); System.out.println(path2.getRoot()); // Path getFileName() : 返回与调用 Path 对象关联的文件名 System.out.println(path1.getFileName() + “~”); System.out.println(path2.getFileName() + “~”); // int getNameCount() : 返回Path 根目录后面元素的数量 // Path getName(int idx) : 返回指定索引位置 idx 的路径名称 for (int i = 0; i < path1.getNameCount(); i++) {

    1. System.out.println(path1.getName(i) + "*****");

    } // Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象 System.out.println(path1.toAbsolutePath()); System.out.println(path2.toAbsolutePath()); // Path resolve(Path p) :合并两个路径,返回合并后的路径对应的Path对象 Path path3 = Paths.get(“d:\“, “nio”); Path path4 = Paths.get(“nioo\hi.txt”); path3 = path3.resolve(path4); System.out.println(path3);

    // File toFile(): 将Path转化为File类的对象 File file = path1.toFile();//Path—->File的转换 Path newPath = file.toPath();//File—->Path的转换 }

  1. **Files类**<br />java.nio.file.Files用于操作文件或目录的工具类<br />**常用方法**<br />`**Path copy(Path src, Path dest, CopyOption … how)**`文件的复制<br />要想复制成功,要求path1对应的物理上的文件存在。path1对应的文件没有要求<br />Files.copy(path1, path2, StandardCopyOption.REPLACE_EXISTING);<br />`**Path createDirectory(Path path, FileAttribute<?> … attr)**`创建一个目录<br />要想执行成功,要求path对应的物理上的文件目录不存在。一旦存在,抛出异常<br />`**Path createFile(Path path, FileAttribute<?> … arr)**`创建一个文件<br />要想执行成功,要求path对应的物理上的文件不存在。一旦存在,抛出异常。<br />`**void delete(Path path)**`删除一个文件/目录,如果不存在,执行报错<br />`**void deleteIfExists(Path path)**`Path对应的文件/目录如果存在,执行删除.如果不存在,正常执行结束<br />`**Path move(Path src, Path dest, CopyOption … how)**` src 移动到 dest 位置<br />要想执行成功,src对应的物理上的文件需要存在,dest对应的文件没有要求<br />`**long size(Path path)**`返回 path 指定文件的大小
  2. ```java
  3. @Test
  4. public void test1() throws IOException{
  5. Path path1 = Paths.get("d:\\nio", "hello.txt");
  6. Path path2 = Paths.get("atguigu.txt");
  7. // Path copy(Path src, Path dest, CopyOption … how) : 文件的复制
  8. //要想复制成功,要求path1对应的物理上的文件存在。path1对应的文件没有要求。
  9. // Files.copy(path1, path2, StandardCopyOption.REPLACE_EXISTING);
  10. // Path createDirectory(Path path, FileAttribute<?> … attr) : 创建一个目录
  11. //要想执行成功,要求path对应的物理上的文件目录不存在。一旦存在,抛出异常。
  12. Path path3 = Paths.get("d:\\nio\\nio1");
  13. // Files.createDirectory(path3);
  14. // Path createFile(Path path, FileAttribute<?> … arr) : 创建一个文件
  15. //要想执行成功,要求path对应的物理上的文件不存在。一旦存在,抛出异常。
  16. Path path4 = Paths.get("d:\\nio\\hi.txt");
  17. // Files.createFile(path4);
  18. // void delete(Path path) : 删除一个文件/目录,如果不存在,执行报错
  19. // Files.delete(path4);
  20. // void deleteIfExists(Path path) : Path对应的文件/目录如果存在,执行删除.如果不存在,正常执行结束
  21. Files.deleteIfExists(path3);
  22. // Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置
  23. //要想执行成功,src对应的物理上的文件需要存在,dest对应的文件没有要求。
  24. // Files.move(path1, path2, StandardCopyOption.ATOMIC_MOVE);
  25. // long size(Path path) : 返回 path 指定文件的大小
  26. long size = Files.size(path2);
  27. System.out.println(size);
  28. }
  • 用于判断

**boolean exists(Path path, LinkOption … opts)**判断文件是否存在
**boolean isDirectory(Path path, LinkOption … opts)**判断是否是目录
不要求此path对应的物理文件存在
**boolean isRegularFile(Path path, LinkOption … opts)**判断是否是文件
**boolean isHidden(Path path)**判断是否是隐藏文件
要求此path对应的物理上的文件需要存在。才可判断是否隐藏。否则,抛异常。
**boolean isReadable(Path path)**判断文件是否可读
**boolean isWritable(Path path)**判断文件是否可写
**boolean notExists(Path path, LinkOption … opts)**判断文件是否不存在

  1. @Test
  2. public void test2() throws IOException{
  3. Path path1 = Paths.get("d:\\nio", "hello.txt");
  4. Path path2 = Paths.get("atguigu.txt");
  5. // boolean exists(Path path, LinkOption … opts) : 判断文件是否存在
  6. System.out.println(Files.exists(path2, LinkOption.NOFOLLOW_LINKS));
  7. // boolean isDirectory(Path path, LinkOption … opts) : 判断是否是目录
  8. //不要求此path对应的物理文件存在。
  9. System.out.println(Files.isDirectory(path1, LinkOption.NOFOLLOW_LINKS));
  10. // boolean isRegularFile(Path path, LinkOption … opts) : 判断是否是文件
  11. // boolean isHidden(Path path) : 判断是否是隐藏文件
  12. //要求此path对应的物理上的文件需要存在。才可判断是否隐藏。否则,抛异常。
  13. // System.out.println(Files.isHidden(path1));
  14. // boolean isReadable(Path path) : 判断文件是否可读
  15. System.out.println(Files.isReadable(path1));
  16. // boolean isWritable(Path path) : 判断文件是否可写
  17. System.out.println(Files.isWritable(path1));
  18. // boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在
  19. System.out.println(Files.notExists(path1, LinkOption.NOFOLLOW_LINKS));
  20. }

补充
**StandardOpenOption.READ**表示对应的Channel是可读的
**StandardOpenOption.WRITE**表示对应的Channel是可写的
**StandardOpenOption.CREATE**如果要写出的文件不存在,则创建。如果存在,忽略
**StandardOpenOption.CREATE_NEW**如果要写出的文件不存在,则创建。如果存在,抛异常

  • 用于操作内容

**InputStream newInputStream(Path path, OpenOption…how)**获取InputStream对象
**OutputStream newOutputStream(Path path, OpenOption…how)**获取OutputStream对象
**SeekableByteChannel newByteChannel(Path path, OpenOption…how)**获取与指定文件的连接,how指定打开方式。
**DirectoryStream<Path> newDirectoryStream(Path path)**打开path指定的目录

  1. @Test
  2. public void test3() throws IOException{
  3. Path path1 = Paths.get("d:\\nio", "hello.txt");
  4. // InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
  5. InputStream inputStream = Files.newInputStream(path1, StandardOpenOption.READ);
  6. // OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象
  7. OutputStream outputStream = Files.newOutputStream(path1, StandardOpenOption.WRITE,StandardOpenOption.CREATE);
  8. // SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接,how 指定打开方式。
  9. SeekableByteChannel channel = Files.newByteChannel(path1, StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
  10. // DirectoryStream<Path> newDirectoryStream(Path path) : 打开 path 指定的目录
  11. Path path2 = Paths.get("e:\\teach");
  12. DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path2);
  13. Iterator<Path> iterator = directoryStream.iterator();
  14. while(iterator.hasNext()){
  15. System.out.println(iterator.next());
  16. }
  17. }

apache-common

第三方开源jar包,提供便捷的IO流操作

  1. public class FileUtilsTest {
  2. public static void main(String[] args) {
  3. File srcFile = new File("day10\\爱情与友情.jpg");
  4. File destFile = new File("day10\\爱情与友情2.jpg");
  5. try {
  6. FileUtils.copyFile(srcFile,destFile);
  7. } catch (IOException e) {
  8. e.printStackTrace();
  9. }
  10. }
  11. }