黑马程序员__IO流

 ------- android培训java培训、期待与您交流! ----------

 

 

 

IO流--字符流。
IO流用来处理设备之间的数据。
java对数据的操作是通过流的方式进行的
java用于操作的流对象都在IO包中
流按照操作数据分为字节流和字符流
流按照流向分为输入流和输出流。

为什么有字符流的存在?
大写A 65  小写 a 97 ASCII码中的编码形式
汉字的编码 是GB2312收录几千个中文文字和标点,扩容之后叫做GBK,后面还有扩容。
国际标准化组织的编码表 Unicode码表,16个位表示一个字符,优化之后叫做UTF-8.这样出现一个问题,一个数字对应多个不同码表中的内容。如果写中文存入电脑中时查的是其他码表会产生乱码。java问了解决这个问题就产生了字符流,就是说字符流可以指定码表进行处理。文字用字符流,图片等这样的数据用字节流。通用字节流,因为字符流基于字节流。
字节流的两个抽象基类
InputStream,OutputStream.
字符流的抽象基类
Reader Writer
他们的子类后缀都会继承类名。


Writer
体系中主要方法就是写。
数据最常见的表现形式就是文件。
那么先以操作文件来演示这个类的功能

FileWriter//专门用于操作文件的Writer子类对象。
此类没有空参数的构造方法,这个流对象一初始化就应该有可以写入数据的文件存在。

FileWriter fw=new FileWriter ("k:\\demo.txt")//路径写错,写成不存在的路径。所以会抛异常,必须抛异常,或者捕捉,自己处理。
以上代码创建了一个流类对象,该文件会被创建到指定的目下,如果当前目录下有同名文件,将会覆盖该文件。

fw.write("abcd");//写入了字符串数据,写入了流当中,流在内存中,也就是写入了内存。
fw.flush();//将缓冲区中临时存放的数据清空,并存入与该流关联的文件中。
此时这个demo.txt文件中将会存入abcd.
fw.close();//关闭流资源,关闭之前会刷新一次流内部缓冲中的数据。同样会刷入关联文件中。flush()刷新后,流可以继续使用,close刷新后流不能再使用。实际上,java是在调用系统内部的方法完成数据的书写。所以使用完就需要关闭这些资源。

这些方法的调用会发生IO异常,所以需要进行相关处理。以下是常用的处理方式。


FileWriter fw=null
try{
fw=new FileWriter ("k:\\demo.txt");//这么写才成功。
//FileWriter fw=new FileWriter ("k:\\demo.txt");//此变量在try中建立无法被捕获,所以应该先在外面建立引用。
fw.write("abcd");

}catch(IOException e){

system.out.println("catch:"+e.toString())
}finally{
//fw.close();//fw创建对象可能不会成功,所以这里调用方法会抛异常,也要处理。
   try{
   if(fw!=null)
       fw.close();

   }catch(IOexception e){

     system.out.printlnt(e.toString();)
    }
}
记住:有些功能如果是给别人去用的,可能会发生异常,那么声明异常就行,让调用者去处理。

以下代码模拟readLine方法的读一行
StringBuilder sb=new StringBuilder();
int ch=0;//定义一个接收read方法返回值的int类型,方便用于判断是否读到末尾。此方法应该定义在一个类中,相当于自己写了一个人BufferedReader类,并且该类中应该有一个Reader类成员用于调用read方法,该类还需要继承Reader类。因为作为缓冲类,它增强的只是某一个功能,而其它功能的实现还得去继承,比如说close方法。
while((ch=r.read())!=-1){//是基于read方法
  if(ch=='\r')
       continue;//因为后面可能会有\n,所以继续读。
   if(ch=='\n')
       return sb.toString();//代表读到行的结尾处,返回一行数据。
   else
       sb.toString();//否则,继续添加。
}
 
if(sb.toString!=null)
      return sb.toString();//如果读到最后一行,是没有回车符的,这时候判断一下sb中有没有数据,有就返回。
return null;


装饰设计模式,当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有对象的功能并提供加强功能,那么自定义的该类就称为装饰类。比如说,这个BufferedReader增强功能readLine就是基于read方法读一行。这个BufferedReader就可以看作是一个装饰类。

装饰设计模式要比继承更加灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。
装饰类因为增强了已有对象,具备功能和已有的是相同的,只不过是提供了更强的功能,所以装饰类和被装饰类通常都属于一个体系中的。是组合结构的一种体现。组合结构就是B类类作为A的一个成员。


一种非常简便的覆盖形式是,直接返回父类方法的返回值。

LineNumberReader同样是装饰类,可以获得行号的装饰类。他是继承自BufferedReader类。

 

IO流--字节流
字节流:
InputStream OutputStream

OutputStream
不同之处就是使用的数组不同,字节流使用字节数组.
void write(byte[] b) 
void write(byte[] b, int off, int len)
方法名还是write

FileOutputStream fos=new FileOutputStram("fos.txt")//创建一个OutputStream的子类字节流。
fos.write("abcd".getBytes();)//字符流同样走的是字节,字符流读多个字节需要缓冲一下(因为需要查表),而字节流不需要查表,不需要刷新。但是流资源需要关闭。字符串转换成字节数组。
fos.close();
InputStream中有一个available用于拿到文件中字节总数,因此可以定义一个刚刚好的byte数组用于依次取完文件中的数据。而不用进行循环操作。但是如果文件过大,则不能这么做。会发生内存溢出。因为是读到内存的流当中,也就是内存中。

同样也有一个BufferedOutputStream类以及BufferedInputStream类作为两个流的缓冲,与字符流不同的是没有读一行的方法,读一个字节,或者读一组字节。
注意:缓冲区是这样的,如果定义了一个读取流类对象关联了一个文件,接着定义这个流的缓冲区的时候,是先把这个文件中的数据弄到缓冲区中,然后重缓冲区当中来读,写的方式也是一样的,这里要理解清楚,不然并不清楚这个缓冲区的意义何在。

字节流需要注意的一点就是,字节流可能会出现读到-1的情况,所以自己定义的缓冲区间需要注意一个问题就是想要保证byte数据在提升到int类型后还能不变,需要&0xff,这将会在前面填充0,之后强转为byte则可以正确拿到数据。(byte数据占8个字节)

字节流中的write方法实际上是做了一个强转的动作,将接收的int强制转换成了byte。

 


 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值