本文转自:http://www.cnblogs.com/littlehann/p/3720396.html

目录

  1. 1. NIONIO.2简介
  2. 2. NIO中的关键技术

1. NIO、NIO.2简介

Java中的输入流、输出流都是阻塞式的输入、输出。不仅如此,传统的输入流、输出流都是通过字节的移动来处理的(即使是字符流,在底层也是通过字节流来进行处理的),也就是说,面向流的输入/输出系统一次只能处理一个字节,因此面向流的输入/输出系统通常效率不高。

从JDK1.4开始,java提供了一系列改进的输入/输出处理的新功能,这些功能被统称为新IO(New IO,简称NIO),新增了许多用于处理输入/输出的类,这些类都被放在java.nio包以及子包下,并且对原java.io包中的许多类都以NIO为基础进行了改写。

  1. NIO和传统的IO有相同的目的,都是用于进行输入/输出,但IO采用内存映射文件的方式来处理输入/输出,新IO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了
    (模拟了操作系统上的虚拟内存的概念),通过这种方式来进行输入/输出比传统的输入/输出要快得多
  2. http://baike.baidu.com/view/394293.htm

java.nio的包层次结构如下

  1. 1. Buffer
  2. java.nio.Buffer: Buffer是一个对象,它包含一些要写入或者刚读出的数据。在NIO中加入Buffer对象,体现了NIO库与传统I/O的一个重要区别。在面向流的I/O中,我们将数据直接写入或者
    将数据直接读到Stream对象中。而在NIO库中,所有数据都是用缓冲区处理的。发送到Channel中的所有对象都必须首先放到Buffer中,而从Channel中读取的数据也必须先放到Buffer中。任何
    时候访问NIO中的数据,我们都是将它放到缓冲区中。缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。这些Buffer类都没有提供构造器,而是通过具体子类: XxxBuffer.allocate(int capaticy); 来创建一个容量为capacityXxxBuffer对象
  3. 1.1) ByteBuffer: 字节数组
  4. 1.1.1) MappedByteBuffer: 用于表示Channel将磁盘文件的部分或者全部内容映射到内存后得到的结果
  5. 1.2) ByteOrder: 字节枚举数组
  6. 1.3) CharBuffer: 字符数组
  7. 1.4) DoubleBuffer: Double数组
  8. 1.5) FloatBuffer: Float数组
  9. 1.6) IntBuffer: Int数组
  10. 1.7) LongBuffer: Long数组
  11. 1.8) ShortBuffer: Short数组
  12. 2. Channel
  13. Channel类似于传统的流对象,但与传统的流对象有两个主要区别:
    1) Channel可以直接将指定文件的部分或者全部直接映射成Buffer2) 程序不能像访问流那样直接访问Channel中的数据(包括读取、写入),Channel只能和Buffer进行交互。即,如果要从Channel中取得数据,必须先使用BufferChannel中取出一些数据,然后让程序再从Buffer中取得这些数据。写入也一样。
  14. Buffer一样,所有的Channel都不应该通过构造器来直接创建吗,而是通过传统的节点InputStreamOutputStreamgetChannel()方法来返回对应的Channel,不同的节点流获得的Channel是不一样的。从这个角度理解,Channel也可以理解为对节点流的一种包装流,这也是Java中著名的装饰器设计模式的一种体现。
  15. 我们按照Channel的功能对Channel的类层次进行分类
  16. 1) 文件操作
  17. 1.1) FileChannel:
  18. 文件读写的通道
  19. 1.1.1) FileInputStream调用getChannel返回的是只能读的FileChannel
  20. 1.1.2) FileOutputStream调用getChannel返回的是只能写的FileChannel
  21. 1.2) AsynchronousFileChannel: NIO.2新增了异步文件操作方式
  22. 1.3) FileLock: 文件锁、互斥读写
  23. 2) 非阻塞式输入输出
  24. 2.1) SelectableChannel
  25. 2.2) Selector
  26. 2.3) SelectionKey
  27. 3) java.nio.channels.Pipe: 线程通信
  28. 3.1) Pipe.SinkChannel: PipedInputStream调用getChanel()返回的是Pipe.SinkChannel
  29. 3.2) Pipe.SourceChannel: PipedOutputStream调用getChanel()返回的是Pipe.SourceChannel
  30. 4) NetworkChannel: 支持TCP网络通信的Channel
  31. 4.1) ServerSocketChannel
  32. 4.2) AsynchronousServerSocketChannel
  33. 4.3) SocketChannel
  34. 4.4) AsynchronousSocketChannel
  35. 5) DatagramChannel: 支持UDP网络通信的Channel
  36. 3. Charset
  37. 计算机底层是没有文本文件的、图片之分的,它只是记录每个文件的二进制数据。当需要保存文本文件时,程序必须先把文件中的每个"字符"翻译成二进制序列,当需要读取文本文件时,程序必须把二进制序列转换成一个个的"字符"java默认使用Unicode字符集,为了解决可能出现的乱码等问题。JDK 1.4提供了Charset来处理字节序列和字符序列(字符串)之间的转换关系
    (单字节、双字节),该类包含了用于创建解码器、编码器的方法。
  38. 1) Charset
  39. 一旦知道了字符集的别名之后,程序就可以调用CharsetforName()方法来创建对应的Charset对象,forName()方法的参数就是相应字符集的别名
  40. 2) CharsetEncoder
  41. 获得了Charset对象之后,就可以通过该对象的newEncoder()方法来返回对应的编码器,调用CharsetEncoderencode()方法可以完成字符序列(CharBufferString)到字节序列
    (ByteBuffer)的转换
  42. 3) CharsetDecoder
  43. 获得了Charset对象之后,就可以通过该对象的newDecoder()方法来返回对应的解码器,调用CharsetDecoderdecode()方法可以完成字节序列(ByteBuffer)到字符序列(CharBufferString)的转换最常用的字符集对应的Charset对象
  44. 4) StandardCharsets
  45. java7新增了一个StandardCharsets类,该类里包含了ISO-8859-1UTF-8UTF-16等静态Field,这些静态Field代表了
  46. 4. java.nio.channels.spi
  47. 主要包含与Channel相关的服务提供者编程接口
  48. 5. java.nio.charset.spi
  49. 包含与字符集相关的服务提供者编程接口
  50. 6. java.nio.file
  51. 早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,它不能利用特定文件系统的特性,File所提供的方法的性能也不高。而且,其大多数方法在出错时仅返回失败,并不会提供异常信息
  52. 1) Path: 代表了一个平台无关的路径
  53. 2) Paths: 包含了2个返回Path的静态工厂方法
  54. 2.1) Path get(String first, String... more): 将给定的多个字符串进行拼接
  55. 2.2) get(URI uri)
  56. 3) Files: 提供了大量的高性能方法来操作文件
  57. 4) FileVisitor
  58. 使用FileVisitor来遍历文件和目录,在编程时可以通过继承SimpleFileVisitor来实现自己的"文件访问器",这样就可以根据需要,选择性地重写指定方法
  59. 5) java.nio.file.attribute
  60. 如果程序希望获取关于文件、目录的更多的和特定操作系统、磁盘个性有关的属性,可以使用NIO.2提供的java.nio.file.attribute工具类来实现
  61. 5.1) FileAttribute
  62. 代表某种文件属性的"集合",程序一般通过XxxAttributeView对象来获取XxxAttribute
  63. 5.1.1) BasicFileAttribute
  64. 5.1.2) DosFileAttribute
  65. 5.1.3) PosixFileAttribute
  66. 5.2) FileAttributeView
  67. 代表某种文件属性的"视图"
  68. 5.2.1) AclFileAttributeView
  69. 为特定的文件设置ACL(Access Control List)、及"文件所有者属性"
  70. 5.2.2) BasicFileAttributeView
  71. 获取或修改文件的基本属性,包括:
  72. 1) 最后修改时间
  73. 2) 最后访问时间
  74. 3) 创建时间
  75. 4) 大小
  76. 5) 是否为目录
  77. 6) 是否为符号链接等
  78. 5.2.3) DosFileAttributeView
  79. 获取或修改文件DOS相关信息,比如:
  80. 1) 是否只读
  81. 2) 是否隐藏
  82. 3) 是否为系统文件
  83. 4) 是否为存档文件等
  84. 5.2.4) FileOwnerAttributeView
  85. 获取或修改文件的所有者
  86. 5.2.5) FileStoreAttributeView
  87. 5.2.6) PosixFileAttributeView
  88. 获取后修改POSIX(Portable Operation System Interface of INIX)属性,用于修改:
  89. 1) 文件的所有者
  90. 2) 组所有者
  91. 3) 访问权限信息(即UNIXchmod命令负责干的事情)
  92. 这个View只在UNIXLinux等系统上有用
  93. 5.2.7) UserDefinedFileAttributeView
  94. 可以让开发者为文件设置一些自定义属性

2. NIO中的关键技术

0x1: Buffer

Buffer中有几个重要的概念:

  1. 1. 容量(capacity): 缓冲区的容量(capacity)表示该Buffer的最大数据容量,即最多可以存储多少数据。缓冲区的容量不可能为负值,创建后不能改变
  2. 2. 界限(limit): 第一个不应该被读出、或者写入的缓冲区位置索引。即位于limit后的数据既不可被读、也不可被写
  3. 3. 位置(position): 用于指明下一个可以被读出、或者写入的缓冲区位置索引(类似IO流中的记录指针)。当使用BufferChannel中读取数据时,position的值等于已经读取了多少数据。
  4. 4. Buffer里还支持一个可选的标记(mark,类似于传统IO流中的mark),Buffer允许直接将position定位到该mark
  5.  
  6. 0 <= mark <= position <= limit <= capacity

Buffer类主要作用就是装入数据、然后输出数据,类中包含几个重要的方法:

  1. 1. 开始时Bufferposition0limitcapacity,程序可以通过put()方法向Buffer中放入一些数据,每放入一些数据,Bufferposition相应地向后移动一些位置(记住,position
    是一个记录指针)
  2. 2. put()
  3. 1) 相对(Relative)写入:
  4. Buffer的当前position处开始写入数据,然后将位置(position)的值按处理元素的个数增加
  5. 2) 绝对(Absotute)写入:
  6. 直接根据索引向Buffer中指定位置开始写入数据,但并不影响位置(position)的值
  7. 3. get()
  8. 1) 相对(Relative)读取:
  9. Buffer的当前position处开始读取数据,然后将位置(position)的值按处理元素的个数增加
  10. 2) 绝对(Absotute)读取:
  11. 直接根据索引向Buffer中指定位置开始读取数据,但并不影响位置(position)的值
  12. 4. flip()
    Buffer装入数据结束后,调用Bufferflip()方法,该方法将limit设置为position所在的位置,并将position设置为0(这里要重点注意,相当于将整个Buffer收缩了)。也就是说,
    Buffer调用flip()方法之后,Buffer就为输出数据做好了准备
  13. 5. clear()
    Buffer输出数据结束后,Buffer调用clear()方法,clear()方法不是清空Buffer的数据,它仅仅将position设置为0,将limit设置为capacity,这样就为再次向Buffer中装入数据
    做好了准备(注意,此时Buffer中的数据被檫除了吗?没有)
  14.  
  15. 我们可以类比思考:
  16. Buffer的这种数据读取机制是一种典型的"基于数据结构的数据操作方式",和操作系统的栈内存操作方式从原理上是一致的

code:

  1. import java.nio.*;
  2.  
  3. public class BufferTest
  4. {
  5. public static void main(String[] args)
  6. {
  7. // 创建Buffer
  8. CharBuffer buff = CharBuffer.allocate(8); //①
  9. System.out.println("capacity: " + buff.capacity());
  10. System.out.println("limit: " + buff.limit());
  11. System.out.println("position: " + buff.position());
  12. // 放入元素
  13. buff.put('a');
  14. buff.put('b');
  15. buff.put('c'); //②
  16. System.out.println("加入三个元素后,position = " + buff.position());
  17. // 调用flip()方法
  18. buff.flip(); //③
  19. System.out.println("执行flip()后,limit = " + buff.limit());
  20. System.out.println("position = " + buff.position());
  21. // 取出第一个元素
  22. System.out.println("第一个元素(position=0):" + buff.get()); // ④
  23. System.out.println("取出一个元素后,position = " + buff.position());
  24. // 调用clear方法
  25. buff.clear(); //⑤
  26. System.out.println("执行clear()后,limit = " + buff.limit());
  27. System.out.println("执行clear()后,position = " + buff.position());
  28. System.out.println("执行clear()后,缓冲区内容并没有被清除:" + "第三个元素为:" + buff.get(2)); // ⑥
  29. System.out.println("执行绝对读取后,position = " + buff.position());
  30. }
  31. }

0x2: Channel

Channel中最常用的方法是:

  1. 1. map()
  2. 用于将Channel对应的部分、或全部数据映射成Buffer
  3. MappedByteBuffer map(FileChannel.MapMode mode, long position, long size)
  4. 1) FileChannel.MapMode: 执行映射时的模式
  5. 1.1) PRIVATE: private (copy-on-write,写时复制) mapping
  6. 1.2) READ_ONLY: Mode for a read-only mapping
  7. 1.3) READ_WRITE: Mode for a read/write mapping
  8. 2) positionlong size决定哪些数据被映射成Buffer
  9. 2. read()
  10. 用于从Buffer中读取数据
  11. 3. write()
  12. 用于向Buffer中写入数据

code:

  1. import java.io.*;
  2. import java.nio.*;
  3. import java.nio.channels.*;
  4. import java.nio.charset.*;
  5.  
  6. public class FileChannelTest
  7. {
  8. public static void main(String[] args)
  9. {
  10. File f = new File("FileChannelTest.java");
  11. try(
  12. // 创建FileInputStream,以该文件输入流创建FileChannel
  13. FileChannel inChannel = new FileInputStream(f).getChannel();
  14. // 以文件输出流创建FileBuffer,用以控制输出
  15. FileChannel outChannel = new FileOutputStream("out.txt").getChannel())
  16. {
  17. // 将FileChannel里的全部数据映射成ByteBuffer
  18. MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY , 0 , f.length()); // ①
  19. // 使用GBK的字符集来创建解码器
  20. Charset charset = Charset.forName("GBK");
  21. // 直接将buffer里的数据全部输出
  22. outChannel.write(buffer); // ②
  23. // 再次调用buffer的clear()方法,复原limit、position的位置
  24. buffer.clear();
  25. // 创建解码器(CharsetDecoder)对象
  26. CharsetDecoder decoder = charset.newDecoder();
  27. // 使用解码器将ByteBuffer转换成CharBuffer
  28. CharBuffer charBuffer = decoder.decode(buffer);
  29. // CharBuffer的toString方法可以获取对应的字符串
  30. System.out.println(charBuffer);
  31. }
  32. catch (IOException ex)
  33. {
  34. ex.printStackTrace();
  35. }
  36. }
  37. }

有时候,如果遇到Channel对应的文件太大,无法一次性全部Map到内存中、或者使用map()方法一次将所有的文件内容映射到内存中会引起性能下降,也可以使用Channel的Buffer的"分批逐段读取"的方法

  1. import java.io.*;
  2. import java.nio.*;
  3. import java.nio.channels.*;
  4. import java.nio.charset.*;
  5.  
  6. public class ReadFile
  7. {
  8. public static void main(String[] args) throws IOException
  9. {
  10. try(
  11. // 创建文件输入流
  12. FileInputStream fis = new FileInputStream("ReadFile.java");
  13. // 创建一个FileChannel
  14. FileChannel fcin = fis.getChannel())
  15. {
  16. // 定义一个ByteBuffer对象,用于重复取水
  17. ByteBuffer bbuff = ByteBuffer.allocate(64);
  18. // 将FileChannel中数据放入ByteBuffer中
  19. while( fcin.read(bbuff) != -1 )
  20. {
  21. // 锁定Buffer的空白区
  22. bbuff.flip();
  23. // 创建Charset对象
  24. Charset charset = Charset.forName("GBK");
  25. // 创建解码器(CharsetDecoder)对象
  26. CharsetDecoder decoder = charset.newDecoder();
  27. // 将ByteBuffer的内容转码
  28. CharBuffer cbuff = decoder.decode(bbuff);
  29. System.out.print(cbuff);
  30. // 将Buffer初始化,为下一次读取数据做准备
  31. bbuff.clear();
  32. }
  33. }
  34. }
  35. }

可以看到,代码每次读取数据后调用flip()方法将没有数据的区域"封印"起来,避免程序从Buffer中读取null值

0x3: Charset

  1. import java.nio.*;
  2. import java.nio.charset.*;
  3.  
  4. public class CharsetTransform
  5. {
  6. public static void main(String[] args) throws Exception
  7. {
  8. // 创建简体中文对应的Charset
  9. Charset cn = Charset.forName("GBK");
  10. // 获取cn对象对应的编码器和解码器
  11. CharsetEncoder cnEncoder = cn.newEncoder();
  12. CharsetDecoder cnDecoder = cn.newDecoder();
  13. // 创建一个CharBuffer对象
  14. CharBuffer cbuff = CharBuffer.allocate(8);
  15. cbuff.put('孙');
  16. cbuff.put('悟');
  17. cbuff.put('空');
  18. cbuff.flip();
  19. // 将CharBuffer中的字符序列转换成字节序列
  20. ByteBuffer bbuff = cnEncoder.encode(cbuff);
  21. // 循环访问ByteBuffer中的每个字节
  22. for (int i = 0; i < bbuff.capacity() ; i++)
  23. {
  24. System.out.print(bbuff.get(i) + " ");
  25. }
  26. // 将ByteBuffer的数据解码成字符序列
  27. System.out.println("\n" + cnDecoder.decode(bbuff));
  28. }
  29. }

实际上,Charset类也提供了如下3个方法,无须创建相应的解码、编码器就可以直接进行编码转换,是否创建编码、解码器的差别我觉得和在进行和正则有关的编程的时候是否创建正则表达式的编译后对象是一个原理,复用性、性能的原因

  1. 1. CharBuffer decode(ByteBuffer bb)
  2. ByteBuffer中的字节序列转换成字符序列的快捷方法
  3. 2. ByteBuffer encode(CharBuffer cb)
  4. ByteBuffer中的字节序列转换成字符序列的快捷方法
  5. 3. ByteBuffer encode(String str)
  6. CharBuffer中的字符序列转换成字节序列的快捷方法

0x4: FileLock

文件锁在操作系统中是很平常的事情,如果多个程序需要并发修改同一个文件时,程序之间需要通过锁机制来进行并发控制。从JDK 1.4的NIO开始,java开始提供文件锁的支持。在NIO中,FileChannel调用lock()、tryLock()方法返回的FileLock可以支持文件锁功能,这两种锁的特性如下

  1. 1. lock()
  2. FileLock lock(long position, long size, boolean shared)
  3. 1) positionsize表明对文件的一部分进行加锁,这是一种细粒度的锁机制
  4. 2) 参数shared
  5. 2.1) true: 表明是一个"共享锁",它将允许多个进行来"读取(注意: 只是读取)",但阻止其他进程获得对该文件的排它锁
  6. 2.2) false(默认值): 表明是一个"排它锁",它将锁住对该文件的读写
  7. 程序可以通过FileLockisShared来判断它获得的锁是否为共享锁
  8. 当调用lock()试图锁定某个文件时,如果无法获得文件锁,该方法将一直阻塞
  9. 2. tryLock()
  10. tryLock()是"尝试"锁定文件,它将立即返回而不是阻塞,如果获得了文件锁,该方法返回文件锁,否则返回null

code:

  1. import java.io.*;
  2. import java.nio.*;
  3. import java.nio.channels.*;
  4.  
  5. public class FileLockTest
  6. {
  7. public static void main(String[] args) throws Exception
  8. {
  9.  
  10. try(
  11. // 使用FileOutputStream获取FileChannel
  12. FileChannel channel = new FileOutputStream("a.txt").getChannel())
  13. {
  14. // 使用非阻塞式方式对指定文件加锁
  15. FileLock lock = channel.tryLock();
  16. // 程序暂停10s
  17. Thread.sleep(10000);
  18. // 释放锁
  19. lock.release();
  20. }
  21. }
  22. }

从以上代码可以看到,在这10秒内,其他程序无法对a.txt进行修改

aaarticlea/png;base64,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" alt="" />

0x5: Path、Paths、Files

path

  1. import java.io.*;
  2. import java.net.*;
  3. import java.nio.file.*;
  4.  
  5. public class PathTest
  6. {
  7. public static void main(String[] args)
  8. throws Exception
  9. {
  10. // 以当前路径来创建Path对象
  11. Path path = Paths.get(".");
  12. System.out.println("path里包含的路径数量:" + path.getNameCount());
  13. System.out.println("path的根路径:" + path.getRoot());
  14. // 获取path对应的绝对路径。
  15. Path absolutePath = path.toAbsolutePath();
  16. System.out.println(absolutePath);
  17. // 获取绝对路径的根路径
  18. System.out.println("absolutePath的跟路径:" + absolutePath.getRoot());
  19. // 获取绝对路径所包含的路径数量
  20. System.out.println("absolutePath里包含的路径数量:" + absolutePath.getNameCount());
  21. System.out.println(absolutePath.getName(3));
  22. // 以多个String来构建Path对象
  23. Path path2 = Paths.get("g:" , "publish" , "codes");
  24. System.out.println(path2);
  25. }
  26. }

Files

  1. import java.nio.file.*;
  2. import java.nio.charset.*;
  3. import java.io.*;
  4. import java.util.*;
  5.  
  6. public class FilesTest
  7. {
  8. public static void main(String[] args) throws Exception
  9. {
  10. // 复制文件
  11. Files.copy(Paths.get("FilesTest.java") ,new FileOutputStream("out.txt"));
  12. // 判断FilesTest.java文件是否为隐藏文件
  13. System.out.println("FilesTest.java是否为隐藏文件:" + Files.isHidden(Paths.get("FilesTest.java")));
  14. // 一次性读取FilesTest.java文件的所有行
  15. List<String> lines = Files.readAllLines(Paths.get("FilesTest.java"), Charset.forName("gbk"));
  16. System.out.println(lines);
  17. // 判断指定文件的大小
  18. System.out.println("FilesTest.java的大小为:" + Files.size(Paths.get("FilesTest.java")));
  19. List<String> poem = new ArrayList<>();
  20. poem.add("水晶潭底银鱼跃");
  21. poem.add("清徐风中碧竿横");
  22. // 直接将多个字符串内容写入指定文件中
  23. Files.write(Paths.get("pome.txt") , poem, Charset.forName("gbk"));
  24. FileStore cStore = Files.getFileStore(Paths.get("C:"));
  25. // 判断C盘的总空间,可用空间
  26. System.out.println("C:共有空间:" + cStore.getTotalSpace());
  27. System.out.println("C:可用空间:" + cStore.getUsableSpace());
  28. }
  29. }

从代码可以看出,Files类是一个高度封装的工具类,它提供了大量的工具方法来完成文件复制、读取文件内容、写入文件内容等功能,简化原本的文件IO代码量

0x6: FileVisitor

在传统的java.io.File文件类的模式下,如果我们想要遍历指定目录下的所有文件和目录,则只能使用递归进行遍历,有了NIO的Files类的帮助,程序员可以采用更优雅的方式来遍历文件和子目录,Files类提供了如下两个方法来遍历文件和子目录

  1. 1. walkFileTree(Path start, FileVisitor<? super Path> visitor);
  2. 遍历start路径下的所有文件和子目录
  3. 2. walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor);
  4. 作用和1一样,增加了控制遍历深度的maxDepth参数

这两个方法都需要FileVisitor参数,FileVisitor代表一个"文件访问器",walkFileTree()方法会自动遍历start路径下的所有文件和子目录,遍历文件和子目录都会"触发"(回调的思想)FileVisitor中相应的方法

  1. 1. FileVisitResult postVisitDirectory(T dir, IOException exc)
  2. 访问子目录之后触发该方法
  3. 2. FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  4. 访问子目录前触发该方法
  5. 3. FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  6. 访问file文件时触发该方法
  7. 4. FileVisitResult visitFileFailed(T file, IOException exc)
  8. 访问file文件失败时触发该方法

以上4个方法都返回一个FileVisitResult对象,它是一个枚举类,代表了访问之后的后续行为。FileVisitResult定义了如下几种后续行为

  1. 1. CONTINUE
  2. 代表"继续访问"的后续行为
  3. 2. SKIP_SIBLINGS
  4. 代表"继续访问"的后续行为,但不访问该文件或目录的兄弟文件或目录
  5. 3. SKIP_SUBTREE
  6. 代表"继续访问"的后续行为,但不访问该文件后目录的子目录树
  7. 4. TERMINATE
  8. 代表"终止访问"的后续行为

code:

  1. import java.io.*;
  2. import java.nio.file.*;
  3. import java.nio.file.attribute.*;
  4.  
  5. public class FileVisitorTest
  6. {
  7. public static void main(String[] args) throws Exception
  8. {
  9. // 遍历g:\publish\codes\15目录下的所有文件和子目录
  10. Files.walkFileTree(Paths.get("D:", "学习资料", "视频学习资料", "JAVA学习", "疯狂java", "code", "codes", "15"), new SimpleFileVisitor<Path>()
  11. {
  12. // 访问文件时候触发该方法
  13. @Override
  14. public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
  15. {
  16. System.out.println("正在访问" + file + "文件");
  17. // 找到了FileInputStreamTest.java文件
  18. if (file.endsWith("FileInputStreamTest.java"))
  19. {
  20. System.out.println("--已经找到目标文件--");
  21. return FileVisitResult.TERMINATE;
  22. }
  23. return FileVisitResult.CONTINUE;
  24. }
  25. // 开始访问目录时触发该方法
  26. @Override
  27. public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
  28. {
  29. System.out.println("正在访问:" + dir + " 路径");
  30. return FileVisitResult.CONTINUE;
  31. }
  32. });
  33. }
  34. }

0x7: 使用WatchService来监控磁盘文件变动

NIO.2的Path类提供了如下的方法来监听文件系统的变动

  1. 1. WatchKey register(WatchService watcher, WatchEvent.Kind<?>[] events, WatchEvent.Modifier... modifiers)
  2. 1) watcher: 代表一个文件系统监听服务,它监听该path代表的目录下的文件变化
  3. 2) events参数指定要监听哪些类型的事件
  4. 2.1) ENTRY_CREATE
  5. 2.2) ENTRY_DELETE
  6. 2.3) ENTRY_MODIFY
  7. 2.4) OVERFLOW

一旦使用register()方法完成注册之后,接下来就可以调用WatchService的方法来获取被监听目录的文件变化事件

  1. 1. WatchKey poll()
  2. 获取下一个WatchKey,如果没有WatchKey发生就立即返回null
  3. 2. WatchKey poll(long timeout, TimeUnit unit)
  4. 尝试等待timeout时间(最大延时)去获取下一个WatchKey
  5. 3. WatchKey take()
  6. 获取下一个WatchKey,如果没有WatchKey发生就一直阻塞等待

code:

  1. import java.io.*;
  2. import java.nio.file.*;
  3. import java.nio.file.attribute.*;
  4.  
  5. public class WatchServiceTest
  6. {
  7. public static void main(String[] args)
  8. throws Exception
  9. {
  10. // 获取文件系统的WatchService对象
  11. WatchService watchService = FileSystems.getDefault().newWatchService();
  12. // 为C:盘根路径注册监听
  13. Paths.get("C:/").register(watchService
  14. , StandardWatchEventKinds.ENTRY_CREATE
  15. , StandardWatchEventKinds.ENTRY_MODIFY
  16. , StandardWatchEventKinds.ENTRY_DELETE);
  17. while(true)
  18. {
  19. // 获取下一个文件改动事件
  20. WatchKey key = watchService.take(); //①
  21. for (WatchEvent<?> event : key.pollEvents())
  22. {
  23. System.out.println(event.context() +" 文件发生了 " + event.kind()+ "事件!");
  24. }
  25. // 重设WatchKey
  26. boolean valid = key.reset();
  27. // 如果重设失败,退出监听
  28. if (!valid)
  29. {
  30. break;
  31. }
  32. }
  33. }
  34. }

0x8: 深度、高效、全面地访问文件属性

  1. import java.io.*;
  2. import java.util.*;
  3. import java.nio.file.*;
  4. import java.nio.*;
  5. import java.nio.charset.*;
  6. import java.nio.file.attribute.*;
  7.  
  8. public class AttributeViewTest
  9. {
  10. public static void main(String[] args) throws Exception
  11. {
  12. // 获取将要操作的文件
  13. Path testPath = Paths.get("AttributeViewTest.java");
  14. // 获取访问基本属性的BasicFileAttributeView
  15. BasicFileAttributeView basicView = Files.getFileAttributeView(testPath , BasicFileAttributeView.class);
  16. // 获取访问基本属性的BasicFileAttributes
  17. BasicFileAttributes basicAttribs = basicView.readAttributes();
  18. // 访问文件的基本属性
  19. System.out.println("创建时间:" + new Date(basicAttribs.creationTime().toMillis()));
  20. System.out.println("最后访问时间:" + new Date(basicAttribs.lastAccessTime().toMillis()));
  21. System.out.println("最后修改时间:" + new Date(basicAttribs.lastModifiedTime().toMillis()));
  22. System.out.println("文件大小:" + basicAttribs.size());
  23. // 获取访问文件属主信息的FileOwnerAttributeView
  24. FileOwnerAttributeView ownerView = Files.getFileAttributeView(testPath, FileOwnerAttributeView.class);
  25. // 获取该文件所属的用户
  26. System.out.println(ownerView.getOwner());
  27. // 获取系统中guest对应的用户
  28. UserPrincipal user = FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName("guest");
  29. // 修改用户
  30. ownerView.setOwner(user);
  31. // 获取访问自定义属性的FileOwnerAttributeView
  32. UserDefinedFileAttributeView userView = Files.getFileAttributeView(testPath, UserDefinedFileAttributeView.class);
  33. List<String> attrNames = userView.list();
  34. // 遍历所有的自定义属性
  35. for (String name : attrNames)
  36. {
  37. ByteBuffer buf = ByteBuffer.allocate(userView.size(name));
  38. userView.read(name, buf);
  39. buf.flip();
  40. String value = Charset.defaultCharset().decode(buf).toString();
  41. System.out.println(name + "--->" + value) ;
  42. }
  43. // 添加一个自定义属性
  44. userView.write("发行者", Charset.defaultCharset().encode("疯狂Java联盟"));
  45. // 获取访问DOS属性的DosFileAttributeView
  46. DosFileAttributeView dosView = Files.getFileAttributeView(testPath, DosFileAttributeView.class);
  47. // 将文件设置隐藏、只读
  48. dosView.setHidden(true);
  49. dosView.setReadOnly(true);
  50. }
  51. }

NIO 01 (转)的更多相关文章

  1. NIO 源码分析(01) NIO 最简用法

    目录 一.服务端 二.客户端 NIO 源码分析(01) NIO 最简用法 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) J ...

  2. NIO复习01

    NIO 概述: 1. Java NIO 由以下几个核心部分组成:Channels       Buffers           Selectors 2. 主要Channel的实现:FileChann ...

  3. NIO入门-----01

    package com.sico.pck01_nio; import java.nio.ByteBuffer; import org.junit.Test; /**  * @author Sico   ...

  4. nio加强服务端并发

    究了一下Android推送,方式很多,比如用框架或者用第三方服务,在此并不讨论个中优劣.抱着学习的态度,本人不太喜欢用一些现成的东西,所以自己动手实现了一套简单的推送机制.使用TCP长连接,完成服务器 ...

  5. java nio之SocketChannel

    Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道.可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器. ...

  6. 基于MINA构建简单高性能的NIO应用

    mina是非常好的C/S架构的java服务器,这里转了一篇关于它的使用感受. 前言MINA是Trustin Lee最新制作的Java通讯框架.通讯框架的主要作用是封装底层IO操作,提供高级的操作API ...

  7. Java NIO教程 前言

    阅读本文前,建议你先了解 旧I/O NIO 是 New I/O 的缩写,要了解它真正的内涵,需要掌握的知识还是比较多的.我努力在这几篇笔记里,勾勒出整个io的面貌.为大家的深入学习铺路. I/O简史 ...

  8. Java I/O NIO学习

    给出一个学习的链接讲的很全.. http://ifeve.com/java-nio-all/ 上边的是中文翻译的这里是原地址:http://tutorials.jenkov.com/java-nio/ ...

  9. java的nio之:java的nio系列教程之java的io和nio的区别

    当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...

随机推荐

  1. 这些孩子在 Ubuntu 的 Linux 终端下玩耍

    导读 我发现了一个孩子们在他们的计算机教室里玩得很开心的视频.我不知道他们在哪里,但我猜测是在印度尼西亚或者马来西亚.视频请自行搭梯子: https://youtu.be/z8taQPomp0Y 在L ...

  2. 【BZOJ5071】[Lydsy十月月赛]小A的数字 发现性质

    [BZOJ5071][Lydsy十月月赛]小A的数字 题解:一般遇到这种奇奇怪怪的操作,常用的套路是将原序列差分一下,或者求个前缀和什么的.本题就是直接对原序列求前缀和,然后发现一次操作相当于交换两个 ...

  3. 微信登陆,微信SDK授权登陆经验分享

    From:http://www.eoeandroid.com/thread-547012-1-1.html 最近因为项目需要做了微信登陆,好像也是微信最近才放出来的接口.还需要申请才能有权限实现授权. ...

  4. Jwt在Java项目中的简单实际应用

    1.什么是jwt 双方之间传递安全信息的简洁的.URL安全的表述性声明规范.JWT作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信 ...

  5. chrome/FF 解析遇到 { 行为一致,返回不一致

    测试的时候,发现一个问题,FF下: chrome 下: 你会发现,FF 在解析一直到返回的时候,都是把 {x:1} 当做一个语句块去解析的,而 chrome 在返回的时候返回了对象,把 {x:1} 当 ...

  6. 常用 Git 操作

    最新博客链接:https://feiffy.cc/Git 日常用到的GIT的一些操作,记下来,以备参考. 删除文件 git rm filename git commit -m "remove ...

  7. JDK的图文安装教程

    JDK的安装 什么是JDK? JDK就是Java开发工具包,即Java Development Kit.就是做Java开发所需要的最基本的工具.包括Java编译器(把人使用的Java语言变成JVM能运 ...

  8. ORACLE安装(12c-Redhat6.5)

    Oracle安装(12c-Redhat6.5) Redhat6.5系统准备 / 10G SWAP 4G /boot 200M /HOME 4G /usr 8G /var 4G /u01 Preinst ...

  9. [转]通过apk签名使应用程序有系统权限

    [转]通过apk签名使应用程序有系统权限 (2013-01-08 13:40:50) 转载▼ 标签: it 分类: Android 出处:http://blog.csdn.net/doom66151/ ...

  10. ArcGIS Server管理工具之批量发布动态地图服务工具.md

    友好阅读链接:(http://swj.me/2015/08/26/batchPublishtools/) update0918: 修复了创建链接文件时而出错的bug 修复了在24011的警告已处理的情 ...