今天正好要写个小程序需要用到io操作,突然想起来java有个nio一直没用过,就找了点资料研究了一下,顺便做点笔记,以便日后查阅。

-------------------------------------------------------------------------------------------------------------------------------------------

编程语言的I/O类库中常使用流的概念,但它屏蔽了实际的I/O设备中处理数据的细节。在Java中很少使用单一的类来创建流对象,而是通过叠合多个对象来提供所期望的功能(用到了装饰器模式)。InputStream和OutputStream就是用来输入和输出的。在Java1.1中,Reader和Writer利用适配器转换了它们来实现国际化,因为老的I/O流继承结果仅支持8位字节流,不能很好的处理16位的Unicode字符。

文件操作的类:FileInputReader,FileOutputReader,RandomAccessFile。其中RandomAccessFile是一个自我独立的类,虽然可读可写,但都是自己内部实现,并没继承输入输出流的层次结构。在JDK1.4中,其大部分功能已经由nio内存映射文件所取代。

基本的文件输出:FileWriter对象可以向文件写入数据,实际上,我们通常会用BufferedWriter将其包装起来用以缓冲输出,为了提供格式化机制,它又被装饰成PrintWriter。例如:new PrintWriter(new BufferedWriter(new FileWriter(file))),在J2SE 5中甲了一个辅助构造器,可以简写成new PrintWriter(file)。

管道流:PipedInputStream,PipedOutputStream,PipedReader及PipedWriter,它们的价值在多线程中才能体现,因为管道流用于任务之间的通信。

-------------------------------------------------------------------------------------------------------------------------------------------

new I/O:目的是为了提高速度,在新版本的JDK中,旧的I/O也使用nio重新实现,有性能提升。速度的提高来自于所使用的结构更接近于操作系统的执行I/O方式——通道和缓冲器。

流使用getChannel()方法会产生一个FileChannel。通道是一种相当基础的东西:可以向它传送用于读写的ByteBuffer,并且可以锁定文件的某些区域用于独占式访问(后面有提到)。

  1. import java.nio.*;
  2. import java.nio.channels.*;
  3. import java.io.*;
  4. public class GetChannel {
  5. private static final int BSIZE = 1024;
  6. public static void main(String[] args) throws Exception {
  7. // Write a file:
  8. FileChannel fc =
  9. new FileOutputStream("data.txt").getChannel();
  10. fc.write(ByteBuffer.wrap("Some text ".getBytes()));
  11. fc.close();
  12. // Add to the end of the file:
  13. fc = new RandomAccessFile("data.txt", "rw").getChannel();
  14. fc.position(fc.size()); // Move to the end
  15. fc.write(ByteBuffer.wrap("Some more".getBytes()));
  16. fc.close();
  17. // Read the file:
  18. fc = new FileInputStream("data.txt").getChannel();
  19. ByteBuffer buff = ByteBuffer.allocate(BSIZE);
  20. fc.read(buff);
  21. buff.flip();
  22. while(buff.hasRemaining())
  23. System.out.print((char)buff.get());
  24. }
  25. }

将字节存放于ByteBuffer有2种方法:一是用put方法直接填充一个或多个字节,或基本数据类型;另一种是用warp方法将已存在的字节数组包装到ByteBuffer中。对于只读访问,我们必须显示的使用静态的allocate方法分配ByteBuffer。nio的目标就是快速移动大量数据,因此ByteBuffer的大小就很重要——需要在实际运行的程序中测试来找到最佳值。要达到更高的速度也有可能,方法就是使用allocateDirect()而不是allocate(),以产生一个与操作系统有更高耦合性的“直接”缓冲器,但效果需要实际测试一下。

  1. import java.nio.*;
  2. import java.nio.channels.*;
  3. import java.io.*;
  4. public class ChannelCopy {
  5. private static final int BSIZE = 1024;
  6. public static void main(String[] args) throws Exception {
  7. if(args.length != 2) {
  8. System.out.println("arguments: sourcefile destfile");
  9. System.exit(1);
  10. }
  11. FileChannel in = new FileInputStream(args[0]).getChannel();
  12. FileChannel out = new FileOutputStream(args[1]).getChannel();
  13. //有一种特殊的办法,将2个通道直接相连
  14. // in = transferTo(0, in.size(), out); 或者 out = transferFrom(in, 0, in.size());
  15. ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
  16. while(in.read(buffer) != -1) {
  17. buffer.flip(); // Prepare for writing
  18. out.write(buffer);
  19. buffer.clear();  // Prepare for reading
  20. }
  21. }
  22. }

BufferWriter转换成char型来操作,很不方便,我们利用CharBuffer的toString()方法来转换成String型就方便多了。

  1. import java.nio.*;
  2. import java.nio.channels.*;
  3. import java.nio.charset.*;
  4. import java.io.*;
  5. public class BufferToText {
  6. private static final int BSIZE = 1024;
  7. public static void main(String[] args) throws Exception {
  8. FileChannel fc =
  9. new FileOutputStream("data2.txt").getChannel();
  10. fc.write(ByteBuffer.wrap("Some text".getBytes()));
  11. fc.close();
  12. fc = new FileInputStream("data2.txt").getChannel();
  13. ByteBuffer buff = ByteBuffer.allocate(BSIZE);
  14. fc.read(buff);
  15. buff.flip();
  16. // Doesn't work:
  17. System.out.println(buff.asCharBuffer());
  18. // Decode using this system's default Charset:
  19. buff.rewind();
  20. String encoding = System.getProperty("file.encoding");
  21. System.out.println("Decoded using " + encoding + ": "
  22. + Charset.forName(encoding).decode(buff));
  23. // Or, we could encode with something that will print:
  24. fc = new FileOutputStream("data2.txt").getChannel();
  25. fc.write(ByteBuffer.wrap(
  26. "Some text".getBytes("UTF-16BE")));
  27. fc.close();
  28. // Now try reading again:
  29. fc = new FileInputStream("data2.txt").getChannel();
  30. buff.clear();
  31. fc.read(buff);
  32. buff.flip();
  33. System.out.println(buff.asCharBuffer());
  34. // Use a CharBuffer to write through:
  35. fc = new FileOutputStream("data2.txt").getChannel();
  36. buff = ByteBuffer.allocate(24); // More than needed
  37. buff.asCharBuffer().put("Some text");
  38. fc.write(buff);
  39. fc.close();
  40. // Read and display:
  41. fc = new FileInputStream("data2.txt").getChannel();
  42. buff.clear();
  43. fc.read(buff);
  44. buff.flip();
  45. System.out.println(buff.asCharBuffer());
  46. }
  47. }

-------------------------------------------------------------------------------------------------------------------------------------------

内存映射文件:它允许我们创建和修改那些因为太大而不能放入内存的文件。

  1. import java.nio.*;
  2. import java.nio.channels.*;
  3. import java.io.*;
  4. import static net.mindview.util.Print.*;
  5. public class LargeMappedFiles {
  6. static int length = 0x8FFFFFF; // 128 MB
  7. public static void main(String[] args) throws Exception {
  8. MappedByteBuffer out =
  9. new RandomAccessFile("test.dat", "rw").getChannel()
  10. .map(FileChannel.MapMode.READ_WRITE, 0, length);
  11. for(int i = 0; i < length; i++)
  12. out.put((byte)'x');
  13. print("Finished writing");
  14. for(int i = length/2; i < length/2 + 6; i++)
  15. printnb((char)out.get(i));
  16. }
  17. }

文件加锁:通过对FileChannel调用tryLock()和lock(),就可以获得整个文件的FileLock。启动tryLock()是非阻塞式的,它设法获取锁,但如果不能获得,将直接放方法调用返回。lock()是阻塞式的,它要阻塞线程直到获得锁,或者调用lock()的线程中断,或者调用lock()的通道关闭。

  1. import java.nio.channels.*;
  2. import java.util.concurrent.*;
  3. import java.io.*;
  4. public class FileLocking {
  5. public static void main(String[] args) throws Exception {
  6. FileOutputStream fos= new FileOutputStream("file.txt");
  7. FileLock fl = fos.getChannel().tryLock();
  8. if(fl != null) {
  9. System.out.println("Locked File");
  10. TimeUnit.MILLISECONDS.sleep(100);
  11. fl.release();
  12. System.out.println("Released Lock");
  13. }
  14. fos.close();
  15. }
  16. }

对映射文件的部分加锁:

  1. import java.nio.*;
  2. import java.nio.channels.*;
  3. import java.io.*;
  4. public class LockingMappedFiles {
  5. static final int LENGTH = 0x8FFFFFF; // 128 MB
  6. static FileChannel fc;
  7. public static void main(String[] args) throws Exception {
  8. fc =
  9. new RandomAccessFile("test.dat", "rw").getChannel();
  10. MappedByteBuffer out =
  11. fc.map(FileChannel.MapMode.READ_WRITE, 0, LENGTH);
  12. for(int i = 0; i < LENGTH; i++)
  13. out.put((byte)'x');
  14. new LockAndModify(out, 0, 0 + LENGTH/3);
  15. new LockAndModify(out, LENGTH/2, LENGTH/2 + LENGTH/4);
  16. }
  17. private static class LockAndModify extends Thread {
  18. private ByteBuffer buff;
  19. private int start, end;
  20. LockAndModify(ByteBuffer mbb, int start, int end) {
  21. this.start = start;
  22. this.end = end;
  23. mbb.limit(end);
  24. mbb.position(start);
  25. buff = mbb.slice();
  26. start();
  27. }
  28. public void run() {
  29. try {
  30. // Exclusive lock with no overlap:
  31. FileLock fl = fc.lock(start, end, false);
  32. System.out.println("Locked: "+ start +" to "+ end);
  33. // Perform modification:
  34. while(buff.position() < buff.limit() - 1)
  35. buff.put((byte)(buff.get() + 1));
  36. fl.release();
  37. System.out.println("Released: "+start+" to "+ end);
  38. } catch(IOException e) {
  39. throw new RuntimeException(e);
  40. }
  41. }
  42. }
  43. }

本文转自passover 51CTO博客,原文链接:http://blog.51cto.com/passover/425926,如需转载请自行联系原作者

《Java编程思想》Java I/O系统章节阅读笔记相关推荐

  1. 71.JAVA编程思想——JAVA与CGI

    71.JAVA编程思想--JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样.而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST ...

  2. 33.JAVA编程思想——JAVA IO File类

    33.JAVA编程思想--JAVA IO File类 RandomAccessFile用于包括了已知长度记录的文件.以便我们能用 seek()从一条记录移至还有一条:然后读取或改动那些记录. 各记录的 ...

  3. 35.JAVA编程思想——JAVA IO StreamTokenizer

    35.JAVA编程思想--JAVA IO StreamTokenizer 尽管StreamTokenizer并不是从 InputStream或 OutputStream衍生的,但它只随同InputSt ...

  4. Java编程思想总结篇(1-11章学习笔记)——第五章

    第五章 初始化与清理 1.用构造器确保初始化 构造器:和类名相同,分无参构造器和有参构造器. 和C++一样,你不写他也会帮你写. 构造器有利于减少错误,并使代码更易阅读.从概念上讲,"初始化 ...

  5. 【Java编程思想】读书笔记(二)第六章---第十章

    Java编程思想(第四版)学习笔记 第六章---第十章 第六章:访问权限控制 6.2Java访问权限修饰词 第七章:复用类 7.1 组合语法 7.2 继承语法(extends) 7.4.2名称屏蔽(重 ...

  6. 【Java编程思想】读书笔记(一)第一章---第五章

    Java编程思想(第四版)学习笔记 第一章---第五章 第一章:对象导论 1.1抽象过程 1. 2访问控制 第二章:一切都是对象 2. 1用引用操纵对象 2. 2基本类型 第三章:操作符 3.7.1测 ...

  7. Java 第一阶段建立编程思想 【房屋出租系统】

    Java 第一阶段建立编程思想 [房屋出租系统] 1. 项目需求说明 2. 项目界面 1. 主菜单 2. 新增房源 3. 查找房源 4. 删除房源 5. 修改房源 6. 房屋列表 7. 退出系统 3. ...

  8. Java编程思想(第4版)(评注版)

    传世经典书丛  Java编程思想(第4版)(评注版)  (美)埃克尔(Eckel, B.)著 刘中兵评注 ISBN 978-7-121-13521-7 2011年6月出版 定    价:108.00元 ...

  9. 【Java编程思想】

    Java编程思想(一) https://blog.csdn.net/weixin_40841731/article/details/83861285 MikeShine 2019.04.22 20:1 ...

最新文章

  1. 搭建zookeeper+kafka集群
  2. nstruts2.0发布前奏---浅谈struts和依赖注入在项目中的应用
  3. shell+ftp+中文乱码_Ftp 命令出现中文乱码问题如何解决,求指教,非常感谢
  4. 一些算法题,欢迎来改进
  5. oracle如何创建视图
  6. 罗森伯格荣获2015年度中国数据中心优秀供应商与中国十大布线品牌两项大奖
  7. pycharm+python3.7+pyqt配置_Python3+Pycharm+PyQt5环境搭建步骤图文详解
  8. slack 团队协作平台
  9. 垂直居中小记 line-height table vertical-align:middle
  10. docker 常用指令
  11. Macbook OBS 录制系统声音
  12. Deeping_Learning 02
  13. 高精度ua级恒流源_高精度恒流源电路图大全(十款高精度恒流源电路设计原理图详解)...
  14. Android HotFix
  15. linux搭建tht框架,教程 中标麒麟linux硬盘安装图解
  16. 可编程式坐标--单位圆坐标
  17. zoho邮箱收费和免费区别_您需要了解有关适用于ios和android的新zoho vault移动应用程序的所有信息...
  18. ORACLE使用dbv工具检验数据文件是否有坏块
  19. 离线安装dotnetfx3.5
  20. elysia Phil‘s Cascade for Mac(硬件音色模拟插件) v1.1破解版

热门文章

  1. AngularJS学习(一)
  2. VS2010+Opencv249 图像叠加 添加水印
  3. ssr Android简书,react服务端渲染ssr
  4. 7-2 整除分块 (15 分)
  5. 计算机网络 HTTP工作机制 TCP三次握手四次挥手 TCP滑动窗口
  6. cwyw不是有效的加载项_ADAS/AD开发09 - UDS与引导加载程序
  7. 外卖行业现状分析_我国外卖行业发展现状与趋势一览
  8. 洛谷 题解 P1135 【奇怪的电梯】
  9. geolocation/ 百度地图api Geolocation 定位当前城市信息
  10. hdu 4454 Stealing a Cake 三分法