16、I/O流

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

1、I/O流
       流的概念:程序与数据来源之间的桥梁
         
        流的分类:
                 按数据方向分:输入流和输出流
                          输入流: InputStream/Reader
                          输出流: OutputStream/Writer
                 按数据类型分:字节流和字符流
                         字节流:InputStream/OutputStream
                         字符流:Reader/Writer
                 按流的功能分:节点流和处理流
                         节点流用操作数据的来源。
                         处理流用来封装节点流,从而给节点流增加一个功能,不能独立存在,在关闭流时如果使用了处理流,只需关闭最外层的流就可以了。
                         区分节点流和处理流的小方法: 看构造器,节点流参数为数据来源,而处理流参数为其他流。
   输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流”(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序)
 2、选择流的思路:
       先考虑是输入流还是输出流,
           输入流: InputStream/Reader
           输出流: OutputStream/Writer
       再考虑是字节流还是字符流,是否是纯文本
            字节流:InputStream/OutputStream
            字符流:Reader/Writer
       最后考虑是节点流还是处理流。具体对象设备
           源:内存,硬盘,键盘
           目的:内存,硬盘,控制台。

3、  读取文件的方式:
   read()方法,一次读一个字符,而且自动向下读
   在read()方法中
   1.可以一次读一个数据,
    FileReader filereader = new FileReader("dome.txt");
    FileWriter filewriter = new FileWriter("dome_copy.txt");
    int ch =0;
    while ((ch= filereader.read())!=-1)
    {
     filewriter.write((char)ch);
    }
    filereader.close();
    filewriter.close();
      2. 也可以定义一个字符数组缓冲区,一次读取指定数组大小的数据
    FileReader filereader = new FileReader("dome.txt");
    FileWriter filewriter = new FileWriter("dome_copy.txt");
    char [] buf=new char[1024];
    int ch =0;
    while ((ch= filereader.read(buf))!=-1)
    {
     filewriter.write(char(buf,0,ch));
    }
    filereader.close();
    filewriter.close();
   
4、  读写流缓冲区: BufferedReader/BufferedWriter
                 以上两个都是过滤流,需要用其他的节点流来作参数构造对象。
                 BufferedReader的方法:readLine() :String ,当他的返回值是null时,就表示读取完毕了。
                 注意:关缓冲流的时候把基本数据流也关闭了
                            再写入时要注意写换行符,否则会出现阻塞。
        使用缓冲区,并且使用readLine方法要记着写完一行要换行 newline()方法和刷新flush(); 

                            BufferedWriter的方法:newLine() ,这个方法会写出一个换行符。 newline()方法只在buffered缓冲流中有缓冲区:就是在内存中开辟一块空间,将硬盘中的数据放到开辟的空间中,以后就直  接对内存中的数据进行操作,读完内存中的数据,再接着把硬盘中的数据写到内存中,直到读完所用数据 
    方法演示: 
     BufferedReader bufr = new BufferedReader(new FileReader("dome.java"));
     BufferedWriter bufw= new BufferedWriter (new FileWriter("dome_copy.txt"));
     String line= null;
     while ((line= bufr.readLine())!=null)//readLine()只返回回车符之前的数据。
     {
      bufw.write(line);
      bufw.newLine();//换行,为了实现跨平台性
     }
     bufr.close();
     bufw.close();

     对缓冲区技术:我们通过自己定义的缓存来解释内部原理
     class myBufferedReader
     {
      private Reader r;
      myBufferedReader(Reader r)
      {
       this.r= r;
      }
       //自定义一个ReadLine方法,
      public String myReadLine()throws IOException
      {
       //定义一个临时容器,一个可变长度的字符串容器。
       StringBuilder sb = new StringBuilder();
       int ch = 0;
       //调用reader中的read的方法,
       while ((ch=r.read())!=-1 )
       {
        if(ch=='\r')//结束判断
         continue;
        if(ch=='\n')//结束判断,
         return sb.toString();//结束判断成功,返回一行字符串,
        else
         sb.append((char)ch);//数据转成字符存入StringBuilder内
       }
       if((sb.length())!=0)//在最后结束判断不成功,对StringBuilder在次进行是否有内容判断
         return sb.toString();
       return null;
       
      }
      public void myClose()throws IOException//复写Reader中的close方法。
      {
       r.close();
      }

                 
        字符流:Reader和Writer是所有字符流的父类型
        字节流: InputStream 和 OutputStream 是所有字节流的父类,
        字节流使用来拷贝字节文件,例如:图片
        它与字符流的用法基本相同,通过read()方法来读取数据,
    字节流缓冲区 BufferedInputStream 和 BufferedOutputStream 应用中也较多应用read()方法,而不支持readLine()方法。
         注意:BufferedInputStream 中没有 readLine() 方法。
    BufferedInputStream bufin= new BufferedInputStream(new FileInputStream ("c:\\1.jpg"));//可以写成相对路径,也可是绝对路径,会抛出异常。
    BufferedOutputStream bufout = new BufferedOutputStream(new FileOutputStream("c:\\2.bmp"));
    int by=0;
    while ((by= bufin.read())!=-1)
    {
     bufout.write(by);
    }
    bufin.close();
    bufout.close();
    第二种
     byte [] buf= new byte[1024];//这里应该有一个功能,可以求出他的字节数多少,以便确定内存大小,以便减少浪费空间。
     int by=0;
    char [] buf=new char[1024];
     while ((by= bufin.read(buf))!=-1)
     {
      bufout.write(buf,o,by);
     }
     bufin.close();
     bufout.close();
      这里需要注意的是读取数据,和写入数据,是把数据读写入流中,必须通过flush()或close()来把数据刷到目的地中
      注意:字节流的flush是没有用的,是一个空方法,在缓冲区的flush才是有用的,
      FileInputStream中的available() 方法返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。也就是文件的大小,所以可以使用byte [] buf=new byte[fis.available() ]定义一个与文件大小一样的数组,但是要慎用,大文件不建议使用
    不能使用字符流操作媒体文件,因为字符流读取字节后先查码表在操作数据
    LineNumberReader extends BufferedReader 是BufferedReader 的子类,但是跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。 默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,并且可以通过调用 setLineNumber(int) 更改行号。
5、桥梁流:InputStreamReader和OutputStreamWriter(字节流转化成字符流的桥转换器)
     这两个类不是用于直接输入输出的,他是将字节流转换成字符流的桥转换器,并可以指定编解码方式。
     OutputStreamWriter outs= new OutputStreamWriter(new FileOutputStream("dome.txt"),"UTF-8"); 
6、  键盘录入:
      1. BufferedReader buf = new BufferedReader( new InputStreamReader(System.in));//默认输入字符串,
    System .in
    一般不需要关闭流操作
      2. Scanner ss= new Scanner(System.in)//可以输入任何数据类型。
     一个用到正则表达式来解析基本数据类型和字符串类型的简单文本扫描器,多线程不安全
    扫描的基本数据类型有,byte,short,int,long,float,double,特别注意的是这样有String类型。
     (a)基本方式:
     Scanner sc = new Scanner(new File("myNumbers"));
       while (sc.hasNextLong()) { //其中的hasNext()判断是否有所数据!
        long aLong = sc.nextLong(); //next输出下一个数据,是什么数据类型就在next跟什么,例:nextLong,nextInt,
       }
      (b)自写例:
      //定义存储数据数组,并定义范围,
      int[] num=new int[5];
     //读取键盘录入
     Scanner s = new Scanner(System.in);
     //遍历数组,把键盘录入数据存入数组。通过Scanner中的nextInt()方法
     for (int x = 0;x < num.length; x++)
     {
      num[x]=s.nextInt(); //数据存入数组中
     }
  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值