Java基础18-IO之字节流

<--
 1.对于一字节文件,使用字符流进行读取,再保存到文件后,数据会丢失:
  使用字符流读取数据的特点:英文字符,读一个字节;中文字符,读两个字节(字符流读取时发现这个字节是负数,那么就会再读取一个字节)
  由于字节数据(byte: -128-127)肯定有负数,那么这时就会再读取一个字节,转换成一个字符,注意由于字符的范围(char: 0-65535),
  当这个字符不存在字符码表中时,就会使用一个字符'?'表示,当全部数据读完后,将数据写入文件时,
  遇到字符'?'时,就会将其当成英文字符'?'处理,将其转成一个字节.这样就丢失了一个字节,所以会出现数据丢失的现象.
 2.字符流读取字节数据时,
  正数,就读一个字节
  负数,读两个字节
 3.方法的返回值类型问题:
  a.对于InputStream的read()方法的返回值是int,而不是byte的原因:
   对于字节数据的读取,到末尾时,需要返回-1,作为结束标记,而byte的范围是:-128-127,-1此时重合了.
   为了能够区分,则会将读取到的字节数据b,进行处理: b & 0xff ,运算结果是int型,这样就解决了上面的问题.
   而且当再将int型的运算结果写入字节流,将int型的高位字节直接丢弃即可.
  b.对于FileReader的read()方法的返回值是int,而不是char的原因:
   对于字符数据的读取,到末尾时,需要返回-1,作为结束标记,而char的范围是:0-65535,无法表示出-1,所以,需要使用int型.
 4.对于可以使用字符流处理的数据,肯定也可以使用字节流进行处理,可能处理会麻烦一点.
 5.转换流的使用需求:
  a.当使用字节流读取到数据后,需要使用字符流进行处理更方便时,我们就可以使用转换流.
  b.对于字符流,比如FileReader,是无法手动指定码表的,只能使用平台默认码表.这时我们就可以使用转换流来处理.
 6.字符流Writer是有write(String s)的方法的(不要忘了!!!)
 7.标准输入与输出流:
  a.System.in: 标准输入流-键盘
  b.System.out: 标准输出流-控制台
 注意:
  可以修改标准输入输出流:
   System.setIn(InputStream in);
   System.setOut(PrintStream out);
-->

 

学过的设计模式:
 1.单态设计模式-SingletonPattern
 2.组合设计模式-CompositePattern
  使用其某个功能而已
 3.模板设计模式-TemplatePattern
 4.策略设计模式-StrategyPattern
 5.装饰设计模式-DecoratorPattern
  功能进行了增强,保证装饰后的类能够当使用的那个类用

 

一.字节流
 1.什么是字节流
  是IO流中的一种, 可以用来读写字节数据.
  
 2.字节流和字符流的区别
  计算机中存储任何数据都是以字节的形式, 所以字节流可以读写任意类型的数据.
  在读写的数据是字符的时候, 用字符流更方便.
  
 3.什么时候用字节流, 什么时候用字符流
  当从一个文本文件中读取数据, 在程序中当作字符使用时, 或者写出一段字符数据到文件中时, 使用字符流比较方便.
   字符流读取数据就是字符, 字符流可以直接写出字符
  如果只是读写数据, 不转为字符, 那么就都可以使用字节流.
  
 4.read()方法为什么返回int: 
  Reader.read() 读取一个字符, 返回int
  InputStream.read() 读取一个字节, 返回int
 问题:为什么不是返回char和byte呢?
  Reader.read() 如果返回char, 那么无法表示流末尾, 因为所有的char都有可能在流中出现.
   在read方法内部, 将读取到的char装入int, 这时正常数据不受影响, 强转回char之后直接使用, 也可以返回-1代表流末尾了.
  InputStream.read() 如果返回byte, 也是无法表示流末尾的, 因为从-128到127中所有值都有可能在流中出现.
   在read方法内部, 是将读取到的字节&255(0xff), 正数没有任何变化, 负数转为了正数, 这时就可以用-1表示文件末尾了
   在真正使用数据时, 只要将转换后的数强转回byte即可
   
 5.使用字节流拷贝文件
  使用FileInputStream和FileOutputStream, 逐个字节拷贝. 效率很低, 不推荐.
  * 使用FileInputStream和FileOutputStream, 定义数组作为缓冲区, 一次读取一个数组, 一次写出一个数组, 提高效率.
  * 使用BufferedInputStream和BufferedOutputStream, 逐个字节拷贝, 但其内部使用了缓冲机制, 速度较快.  

 

二.转换流 (使用转换流的优点之一: 可以定义码表)
 * 1.InputStreamReader
  当获取了一个字节输入流, 希望从中读取字符数据时, 可以把字节输入流转为字符输入流InputStreamReader
  当读取非平台默认编码的字符文件时, FileReader做不到, 只能使用InputStreamReader.
  
 * 2.OutputStreamWriter
  当获取了一个字节输出流, 希望向外写出字符数据时, 可以把字节输出流转为字符输出流OutputStreamWriter
  当写出非平台默认编码的字符文件时, FileWriter做不到, 只能使用OutputStreamWriter

 

三.标准输入输出流
 1.System.in
  标准输入流, InputStream, 可以从键盘输入读取字节.
  可以使用System.setIn(InputStream)改变标准输入流的数据源.!!
  
 2.System.out
  标准输出流, PrintStream, 可以向屏幕输出数据.
  可以使用System.setOut(PrintStream)改变标准输出流的数据目的地. !!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值