字节流和字符流 篇

时间:2021-10-11 21:00:17
字节流和字符流 篇
   字节流 (InputStream|OuputStream)
 in:InputStream子类的对象
(1) 特点:

   InputStream: 抽象了应用程序读数据操作 "读" read()

(2) 读常用方法:   
   int b = in.read(): 读一个字节,然后无符号填充到
    int类型的低8位,int类型其它位补0; 
    注:如果要使用 read() 读取全部内容时,使用

    循环,指出结束条件(指针-1) 

 b.byte[] b = new byte[100]
   int bytes = in.read( b ); 
      一次性读文件内容,将读到的内容放到b数组中
      返回的是:真正读到的总的字节数
 c.in.read( b ,int start,int size):
      一次读文件内容,读到的内容放到b数组中,
      从start位置开始放,放size个字节.

 d. close():关闭流


 OuputStream: 抽象了应用程序写数据操作 "写" write() 
  OutputStream 常用方法:
  a. write(int n): 
     写一个Int数据,但是只写int低8位到文件
     注:如果要向文件中写入很多内容时,循环多次执行     write
  b. write( byte[] b):
     将b 数组中的内容一次性向文件中
     注: b 数组中内容
  c. write( byte[] b,int start,int size) 
     将b 数组中内容一次性写入到文件中,从start位置,
     写size 个
  d. close();关闭流
 (2) 常用的实现类(子类) 
   a.文件流: 文件
    FileInputStream 
    FileOutputStream

FileInputStream fileInputStream = new FileInputStream("d:/text.txt");  

// 定义一个指向D:/TEXT.TXT 的字节流


   b.数据流:针对基本数据类型的数据进行读写操作
    DataInputStream

    DataOutputStream  


  c. 缓冲区流: 
    BufferedInputStream 
    BufferedOutputStream 
  d.管道流:
    PipedInputStream

    PipedOutputStream

字节流与字符流区别:


    1. 处理单位:
         字节流以字节为单位进行数据读写
         可操作的数据:字节,二进制,字节数组


         字符流以字符为单位进行数据读写
         处理的数据: 字符,字符数组,字符串


    2. 读写方式:
         read(): 字节流, 读一个字节,8位,所以对于汉字,
                 可能不能完整显示汉字;
                 而字符流,read()读时,一次读一个字符
                 读一次,可能完整的读出任意一个字符
                 (包括汉字及其它符号)unicode编码
         write():一样


    3. 缓冲区问题:      
         一般的字节流(除BufferedInputStream),
         默认都没有缓冲区,意味向文件中写入数据后,
         即使不使用close,也可以将数据写入到内容
         对于字符流来说,字符流默认都自带一个默认
         容量的缓冲区,意味着使用字符流的write写入
         数据,需要手动刷新缓冲区,才能真正文件;    
    3. 使用场景:
        一般使用字符流,针对纯文本或数据量比较大的
        文本文件进行操作; 
        FileReader|FileWriter 
        BufferedReader|BufferWriter
       
        一般使用字节流,处理的是这种:
        图片文件,音频文件,视频文件
    总结:一般情况,文本文件使用字符流处理,如果可以,
    在最外面嵌套一个缓冲;底层需要二进制处理文件,
    尽量使用字节流读写,以保证数据完整性;
字节流: 常用的字节流不能指定编码 
  
 (1) 常用字节流--构造方法
   FileInputStream (File|String|FileD
   DataInputStream (InputStream in )
   BufferedInputStream (InputStream in, int capitity
   PipedInputStream(PipedOutputStream
   PipedInputStream (int 
   PipedInputStream (无参数
   PipedInputStream (PipedOutputStream, int size)
   FileOutputStream(File|String, boolean append)
  (2) 常用字符流---构造方法
   FileReader (String|File|FileD
   BufferedReader (Reader 
                   Reader , int buffer )
   InputStreamReader (InputStream )
                     (InputStream , String(编码) )
                     (InputStream , Charset encode)

  字符流(转换流)

InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);   
//字节流转换成InputStreamReader 

BufferedReader bufferedReader = new BufferedReader(inputSteamReader);   
//InputStreamReader 转换成带缓存的bufferedReader 

         new  BufferedReader (
             new  FileReader(File | String ) );
    BufferedReader  br = 
         new  BufferedReader (
              new InputStreamReader(
                  new BufferedInputStream (
                       new DataInputStream(
                           new FileInputStream(
                      )
                       )
                 )
       )
              );

    通过分析发现: 字符流与字节流进行转换时,使用的

    转换流 InputStreamReader 


序列化|反序列化
  what:
   什么是序列化和反序列化?
   将Object类型的数据转换为byte序列,序列化
   反之,反序列化.
   "将对象类型的数据写入文件中,称为 序列化"
   "将对象类型的数据从文件中读出来,称为 反序列化"
   
  why:
    1. 如果对象类型的数据实现本地持久化存储;
    2. 如果某对象数据进行网络段传输
    3. 存储对象属性值方便操作
        存以对象
        取以对象
  how: 
   序列化流: ObjectOutputStream "写"

               ---writeObject( *** );


 反序列化流: ObjectInputStream "读"  
               ---readObject();          
  

   实际开发中,对对象进行序列化和反序列化时,
   对象所有属性内容不是全部都需要存储或者传输,
   有些属性的值不需要进行序列和反序列化,
   此时:
   在不需要序列化和反序列化的属性前加: transient 
   此时,再获取这些属性的值时,基本数据类型使用默认值
   0,0.0 false,对象null       
  可以实现.可以自定义序列化和反序列化
  i.  jvm默认的序列化
      创建 流 
      out. writeObject()   
      in.  readObject()
  ii. 自定义序列化和反序列化    
1.查看 ArrayList.java类中的两个方法:
     private void  writeObject(....)
     private void  readObject(.....)
   2. 将writeObject()方法拷贝到实体类中, "写"
    private void writeObejct(OjectOutputStream s) {
           //没有使用transient的属性使用jvm默认序列化
           s.defaultWriteObejct();
          //自定义序列化
           s.writeInt( 属性名 );
    }
 step3. 将readObject()方法拷贝到实体类中 写
      private void readObejct(OjectOutputStream s) {
             s.defaultReadObejct();
             属性名 = s. readInt();

      }