字符char 输入输出流 和 NIO
来源:互联网 发布:java jar 日志输出 编辑:程序博客网 时间:2024/06/07 04:58
字符输入和输出很类似,只不过字符类处理的是字符,
字符流以char为最基本的单位,而字节流以byte为最基本的单位。
字符流 Reader 和 Writer 两个抽象类,字符输入和输出流的类都是继承自这两个类。
Java使用unicode来表示字符和字符串, 一个字符char 用两个字节表示,即一个字符占 16 位。 Java中一个字符 可以表示一个汉字。
OutputStreamWriter类: 用于在字符和字节流之间搭起一座桥, 从程序向文本写数据,从字符流转化为字节流
InputStreamReader类 : 从文本向程序中读数据,从字节流到字符流
这两个类经常被用到, In 和out 是输入和输出字节流对象,带参数的String 参数是 指定的编码格式(如果不指定,表示使用当前平台的编码方式)
其实字符流和字节流的使用大同小异,大家看一下下面的例子就好了
// 从程序向文件中写入信息,再从文件中读取出来public class FileWriterTest { public static void main(String[] args) throws IOException { //向文件中写入字符串, 加在文本文档的后面,而不是覆盖 FileWriter out = new FileWriter("file.txt", true); // 装饰模式把文件流变成一个带缓冲的文件流 BufferedWriter buffOut = new BufferedWriter(out); String str = "hello world \n"; // \n 表示回车 out.write(str); out.write(str); out.write(str); out.close(); // 从文件中读取字符串 FileReader in = new FileReader("file.txt"); BufferedReader buffIn = new BufferedReader(in); String str2 = null; while (null != (str2 = buffIn.readLine())){ System.out.println( str2); } buffIn.close(); }}
几种字符集的编码:
ASCII 码: 美国信息互换标准代码,基于英文字符的编码,包括英文字符,数字,每一个ASCII码和一个8为二进制数对应,数字的表示,最高位是0,能表示的数字是0-127, 最高位为1的表示一些制表符和其他符号。是通用的单字节编码系统。
GB2312: 中国汉字信息交换编码,为每一个中文字符指定相应的数字,一个中文字符 = 两个字节,每个字节的最高位置都为 1。
GBK : 国标扩展,一些生僻字也被加入到GBK编码中
Unicode : 全世界通用的字符集,由两个字节表示, 对于英文字符,一个字节就能表示,因此英文字符的Unicode码的高位字节都为 0。来实现等长兼容。等长的编码
UTF-8: Eight - bit UCS Transformation format, UCS 是一个通用的字符集,是所有其他字符集标准的一个超集,十分适合国际化,
它是不等长的编码方式,比如英文字母的UTF码用一个字节表示,而汉字的UTF码是3个字节。
一个重要的方法获取项目的配置信息
// 获取项目的配置情况 Properties p = System.getProperties(); p.list(System.out);
另外一个重要的文件类:
随机访问文件类 : RandomAccessFile 该文件类既能对文件读也能写,同时提供了 write 和read方法,还能在文件中定位位置,跳到特定数据所在的位置。
RandomAccessFile的唯一父类是Object,与其他流父类不同。是用来访问那些保存数据记录的文件的,这样你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。
RandomAccessFile是不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫不相干,甚至都没有用InputStream和OutputStream已经准备好的功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写的。这可能是因为RandomAccessFile能在文件里面前后移动,使用seek( index) 方法, 可以跳到文件中指定的位置,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。
NIO 新的I/O系统 , 和I/O 的区别
IO NIO
面向流 面向缓冲
阻塞IO 非阻塞IO
无 选择器
第一点: IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据
当程序从硬盘往内存读取数据的时候,操作系统使用了 2 个“小伎俩”来提高性能,那就是预读,如果我读取了第一扇区的第三磁道的内容,那么你很有可能也会使用第二磁道和第四磁道的内容,所以操作系统会把附近磁道的内容提前读取出来,放在内存中,即缓存。
(PS:以上过程简化了)
通过上面可以看到,操作系统是按块 Block从硬盘拿数据,就如同一个大脸盆,一下子就放入了一盆水。但是,当 Java 使用的时候,旧的 IO 确实基于 流 Stream的,也就是虽然操作系统给我了一脸盆水,但是我得用吸管慢慢喝。
第二点: 在以前的 Java IO 中,都是阻塞式 IO,NIO 引入了非阻塞式 IO,
阻塞IO 我从硬盘读取数据,然后程序一直等,数据读完后,继续操作。这种方式是最简单的,叫阻塞IO,
非阻塞式 IO 我从硬盘读取数据,如果数据还没准备好,然后程序继续向下执行,等数据读取完后,通知当前程序(对硬件来说叫中断,对程序来说叫回调),然后此程序可以立即处理数据,也可以执行完当前操作在读取数据。
传统的IO操作,比如read(),当没有数据可读的时候,线程一直阻塞被占用,直到数据到来。NIO中没有数据可读时,read()会立即返回0,线程不会阻塞,该线程可以去帮助其他文件连接读取数据。
传统的I/O需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大。使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数量线程的线程池,甚至一个线程来为任意数量的连接服务。由于线程数量小于连接数量,所以每个线程进行IO操作时就不能阻塞,如果阻塞的话,有些连接就得不到处理,NIO提供了这种非阻塞的能力。
第三点: 选择器(Selectors)
NIO中,客户端创建一个连接后,先要将连接注册到Selector, Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
- 字符char 输入输出流 和 NIO
- 字符和字符串输入输出
- 宽字符 和 Char字符
- char * 和字符数组
- 输入输出 字节,字符流
- 字符流的输入输出
- Java中的字节输入出流和字符输入输出流
- 字符输入输出流:java.io.FileReader和java.io.FileWriter
- Java 输入输出流(输入数字、字符和字符串)
- Java-IO之字符输入输出流(Reader和Writer)
- java7输入输出流中NIO.2
- char和unsigned char字符类型
- Java输入输出流-----字符流
- 文件的字符输入输出流
- 面向字符的输入输出流
- java IO(输入输出) 字符流
- IO(输入输出)-字符流
- char字符数组和字符指针
- Android UI 开发入门—线性布局练习
- 2种方法解决mysql主从不同步
- [转]关于软件测试的几个经典问题(2)
- java创建二叉树及遍历
- 《Linux多线程服务端编程》笔记——线程同步精要
- 字符char 输入输出流 和 NIO
- Mysql 优化之 Explain 执行计划
- Java学习-装箱和拆箱
- leetCode:493. Reverse Pairs
- iMX283 学习笔记----1. GPIO2_4(P2.4) 操作
- 设计模式C++实现(1)——工厂模式
- 各种算法的优缺点
- 华师大 OJ 3036
- Join内外连接基本操作