Java初级--IO流(下)

来源:互联网 发布:mac玫红色口红哪个最火 编辑:程序博客网 时间:2024/05/21 06:12

11.字符编码
       计算机里只有数字,计算机里的一切都是用数字表示的。
       ASCII 码的最高bit 位都是0 。
       GB2312(国标码):中文字符的每个字节的最高位都是1,每一个中文字符用两个字节数字表示。
       Unicode 编码:
       Unicode 编码的字符都占用两个字节的大小。
       UTF-8 编码:ASCII 码字符保持原样,仍然只占有一个字节,对于其它国家的字符,UTF-8 使用两个或三个字节来表示。使用UTF-8 编码的文件,通常都要用EF BB BF 作为文件开头的三个字节数据。


       UTF-8 编码的优点:
             不出现内容为 0x00 字节;
             便于应用程序检测数据传输过程中是否发生错误;
             直接处理使用ASCII 码的英文文档;
       不足之处在于某些字符需要使用三个字节;

 

12.各种过滤流与包装类
      包装类(过滤流类或处理流类):
       FileInputStream、FileOutputStream、PipedInputStream、PipedOutputStream 都是具体的节点流对象,它们对应具体的流设备,只能被别的类包装。

      1)BufferedInputStream 与 BufferedOutputStream 类:
          缓冲流为I/O流增加了内存缓冲区,增加缓冲区有个基本目的:
              允许Java 程序不止一次操作一个字节,这样提高了程序的性能。由于有了缓冲区,使得在流上执行skip 、mark和reset 方法都成为可能。是Java 提供的两个缓冲区包装类,不管底层系统是否使用了缓冲区,这两个类在自己的实例对象中创建缓冲区。


         注:这种方式创建的缓冲区与底层系统提供的缓冲区的区别?
         底层系统提供的缓冲区直接与目标设备交换数据,而在包装类中创建的缓冲区,需要调用包装类所包装的输出流对象,将缓冲区中的数据写入到目标设备或底层的缓冲区,或者调用输入流的包装类对象,从目标设备或底层的缓冲区读取数据到包装类的缓冲区中。底层缓冲区是一次从硬盘中读取大量数据,或者是一次往硬盘中写入大量的数据。包装类缓冲区的特点在于:例如BufferedInputStream一次从底层输入流读取一个数据,将其放在BufferedOutputStream创建的缓冲区中,如此缓冲多个数据后,就可以一次读取一行的数据。另外,若想实现字节数组和字符串之间的转换,如果读到一个字节就将其转换成字符串,这样是不现实的,可以利用BufferedInputStream 将读到的许多个字节一次性的转换成字符串。

 

     2)BufferedReader 和BufferedWriter 类
         BufferedReader 的readLine 方法可以一次读取一行文本,BufferedWriter 的newLine 方法可以向字符流中写入不同操作系统下的换行符。

 

     3)DataInputStream 与DataOutputStream 类
         提供了从IO流中读取各种基本数据类型的方法,
     
注:为什么DataInputStream 类中有一个readUTF 方法,而没有readBytes 和 readChars 方法?
             要在一个连续的字节流读取一个字符串,这个字符串只是这个连续的字节流中的一部分内容,如果没有特殊的标记作为字符串的结尾,而且,事先也不知道字符串的长度,那就无法知道读取到什么位置,才是这个字符串的结尾处,由于DateOutputStream 中的writeUTF 方法,向目标设备中写入了字符串的长度,而writeBytes() 和writeChars()没有向字符串中写入长度,所以DateInputStream类中只有readUTF() 方法;

 

  流栈:(如图)


         关闭流栈中的最上层的流栈对象,将会自动关闭流栈中的所有底层流对象。

 

        4)PrintStream 类
           PrintStream 类提供了一系列的print 和 println 方法,可以将基本数据类型的数据格式化成字符串输出。 经常使用的System.out 就是PrintStream 类的实例对象,PrintStream 类具有多个重载的print 和println 方法。对于基本类型的数据,print 和println 方法会将他们先转换成字符串,再进行输出,而不是将他们原始的字节内容输出。对于非基本数据类型的对象,print 和 println 打印时会先调用对象自己的toString 方法,将其转换成字符串打印出来。

 

        5)格式化输出是什么意思?
            格式化输出是指将一个字符,一个数据按照字符串的格式输出。

 

        6)PrintWrite 类,即使遇到了文本换行标识符(\n),PrintWriter 类也不会自动清空缓冲区。PrintWriter的println 方法能根据操作系统的不同而生成相应的文本换行标示符。在Windows 下的文本换行符是"\r\n",而Linux 下的文本换行标识符是"\n";

 

        7)ObjectInputStream 与ObjectOutputStream 类
           ObjectInputStream 与ObjectOutputStream 这两个包装类,用于从底层输入流中读取对象类型的数据和将对象数据类型的数据写入到底层输出流。这两个类所读写的对象必须实现了Serializable 接口。对象中的transient 和 static 类型的成员变量不会被读取和写入。(static 修饰的变量是全局变量,和这个对象没有多大的关系,transient 作为一种标记,不能作为对象的特征来使用。)Serializable 接口中没有任何的方法,仅仅是作为一种标记,被编译器特殊处理。

 

       8)字节流与字符流的转换
          找到一种简单的方式,来读取键盘上输入的一行字符?
          InputStreamReader 和 OutputStreamWriter ,是用于将字节流转换成字符流来读写的两个类,InputStreamReader 可以将一个字节流中的字节解码成字符后读取,OutputStreamWriter 将字符编码成字节后写入到一个字节流中。
          为了避免频繁地在字符与字节间进行转换,最好不要直接使用InputStreamReader 和OutputStreamWriter 类来读写数据,应尽量使用BufferedWriter 类包装OutputStreamWriter 类,用BufferedReader类包装InputStreamReader。

 

      9)Java 程序与其它进程的数据通信
         在Java程序中可以用Process 类的实例对象来表示子进程,子进程的标准输入和输出不再连接到键盘和显示器,而是以管道流的形式连接到父进程的一个输出流和输入流对象上。调用Process 类的getOutputStream 和getInputStream 方法可以获得连接到子进程的输出流和输入流对象上。记得调用Process 类的destory 方法结束子进程的运行。

   验证管道缓冲区满后,将发生下面的哪种情况:
    a) 新的数据写入时,将最前面写入的数据挤出去,从而发生数据丢失。
    b)与PipedInputStream 相连的PipedOutputStream 无法再写入新的数据,PipedOutputStream.write 方法处于阻塞状态。
    c)与PipedInputStream 相连的PipedOutputStream 无法再写入新的数据,PipedOutputStream.write 方法抛出异常。

 

    10).Io类的相关应用
          ①各种输入流的层次关系图

             


      SequenceInputStream 类的使用:将若干个InputStream 类合并成为一个逻辑的整体的InputStream类,通过SequenceInputStream 类来读取。StringBufferInputStream 类与ByteArrayInputStream 类功能相似,区别就是StringBufferInputStream 是用在字符的缓冲区,ByteArrayInputStream 是用作字节的缓冲区。 FilterInputStream 是所有的输入包装类的基类,如果需要自己定义一个包装类,就需要继承这个类。JDK中提供了一下几个包装类:其中PushbackInputStream 类支持回滚,譬如从流中读取了5个数据,现在又想将其还回去,就可以使用此类。


 2)字节输出流


   FileterOutputStream 是包装类的父类,如果定义自己的包装输出类,就是需要继承FilterOutputStream 类。

 

   3)CharArrayReader 和StringReader 类似,StringReader 用于处理字符串,而CharArrayReader 用于处理字符数组,如果要定义自己的字符输入包装类,要继承FilterReader 类,LineNumberReader 类用于读取字符输入流中一行的数据,并且返回行号。

 

  

 4)Decorator 设计模式
   在程序中只有一个对象(the Decorators)包装应外的一个对象,这是一种被称为Decorator 设计模式。

 

 

 

原创粉丝点击