• Java:IO流之字符流缓冲区详解


    字符流缓冲区:
    1、缓冲区的出现提高了对数据的读写效率;
    2、对应类:BufferedWriter、BufferedReader;
    3、缓冲区要结合流才可以使用;
    4、在流的基础上对流的功能进行了增强。
     
    注意:缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前必须现有流对象。
     
    java.io 
    类 BufferedReader:读入缓冲区
     
    构造方法摘要 
    BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。 
    BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。 
    主要方法摘要 
     void close() 关闭该流并释放与之关联的所有资源。  
     int read() 作为一个整数(其范围从0到65535(0x00-0xffff)读入的字符,如果已到达流末尾,则返回 -1,读取单个字符。 
     int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。 
     String readLine() //包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null ,读取一个文本行。 

     //例子1:

    import java.io.*;
    class BufferedReaderDemo
    {
        public static void main(String[] args) throws IOException
        {
            //创建一个字符读入流对象,和目的地文件相关联.
            FileReader fr = new FileReader("F:\myfile\buf.txt");
            
            //为了提高字符读入流效率,加入了缓冲技术,只需要将被提高效率的流对象作为参数
            //传递给缓冲区的构造函数即可。此时,缓冲区和流相关联.
            BufferedReader buf = new BufferedReader(fr);
            int num = 0;
            String line = null;
            
            /*
            while((line = buf.readLine())!=null) //此过程中,读入缓冲区一行一行的读取数据,效率高
            {
                System.out.println(line);
            }
            */
            
            while((num = buf.read())!=-1)
            {
             System.out.print((char)num);        
            }
    
           //其实关闭缓冲区,就是关闭缓冲区中的流对象
            buf.close();
        }
    }
    readLine方法的原理:尽管是读取一行获取多个字符,其实最终都是在硬盘上一个一个地读取字符。所以最终使用的还是read方法一次读一个的方法。
    明白了BufferedReader类中特有方法readLine的原理后,
    可以自定义一个类中包含一个功能和readLine一致的方法,
    来模拟一个BufferedReader
    (该代码中的思想体现了装饰设计模式)
    //例子2:
    import java.io.*;
    class MyBufferedReader extends Reader
    {
        private Reader r;
        MyBufferedReader(Reader r)
        {
            this.r = r;
        } 
        //可以一次读一行的方法
        public String MyreadLine() throws IOException
        {
         //定义一个临时容器。原BufferedReader封装的是字符数组。
         //为了演示方便,定义一个StringBuilder容器,因为最终还是要将数据变为字符串
          StringBuilder sb = new StringBuilder();
          int ch = 0;
          while((ch=r.read())!=-1)
          {
            if(ch=='
    ')  
                continue;
            if(ch=='
    ')
                return sb.toString();
            else
                sb.append((char)ch);    
          }    
          if(sb.length()!=0)   //出现读取一行数据到了缓冲区,但是该字符串后面没有'
    ',可是仍要把它读取出来。
                return sb.toString();
          return null;      
        }
        //覆盖Reader中的抽象方法
        public int read(char[] cbuf, int off, int len) throws IOException
        {
            return r.(cbuf,off,len);
        }
        public void close()throws IOException
        {
            r.close();
        }
    
        public void Myclose()throws IOException
        {
            r.close();
        }
    }
    //测试类
    class MyBufferedReaderTest { public static void main(String[] args) { FileReader fr = null; MyBufferedReader mybuf = null; String line = null; try { mybuf = new MyBufferedReader(new FileReader("F:\myfile\buf.txt")); while((line = mybuf.MyreadLine())!=null) { System.out.println(line); } } catch(IOException e) { throw new RuntimeException("读入流异常"); } finally { try { mybuf.Myclose(); } catch(IOException e) { throw new RuntimeException("关闭流异常"); } } } }

    自定义一个统计行号的类:MyLineNumberReader,可以设置复制得到的文件内容的行号

    //例子3:
    import java.io.*;
    /*
    class MyLineNumberReader extends MyBufferedReader
    {
        private int linenumber;
        MyLineNumberReader(Reader r)
        {
            super(r);
        }
        public void setLineNumber(int linenumber)
        {
            this.linenumber = linenumber;
        }
        public int getLineNumber()
        {
            return linenumber;
        }
        public String MyreadLine() throws IOException
        {   
            linenumber++;//每读一行,行数就自加一次
            return super.MyreadLine();
        }
    }
    */
    class MyLineNumberReader
    {
        private Reader r;
        private int linenumber;
        MyLineNumberReader(Reader r)
        {
            this.r = r;
        }
        public void setLineNumber(int linenumber)
        {
            this.linenumber = linenumber;
        }
        public int getLineNumber()
        {
            return linenumber;
        }
        public String MyreadLine() throws IOException
        {   
            linenumber++;//每读一行,行数就自加一次
            StringBuilder sb = new StringBuilder();
            int ch = 0;
            while((ch = r.read())!=-1)
            {
                if(ch=='
    ')
                    continue;
                if(ch=='
    ')
                    return sb.toString();
                else
                    sb.append((char)ch);
            }
            if(sb.length()!=0)
                return sb.toString();
            return null;
        }
        public void Myclose() throws IOException
        {
            r.close();
        }
    }
    class MyLineNumberReaderDemo
    {
        public static void main(String[] args)
        {
            FileReader fr = null;
            MyLineNumberReader myl = null;
            String str = null;
            try
            {
              fr  = new FileReader("MyBufferedReaderTest.java");
              myl = new MyLineNumberReader(fr);
              //myl.setLineNumber(100);  //设置第一行从101行开始
              while((str = myl.MyreadLine())!=null)
               {
                 System.out.println(myl.getLineNumber()+":"+str);
               }              
            }
            catch(IOException e)
            {
                System.out.println("流读入异常!");
            }
            finally
            {
                try
                {
                    myl.Myclose();
                }
                catch(IOException e)
                {
                    System.out.println("流关闭异常!");
                }
            
            }        
        }
    }
    java.io 
    类 BufferedWriter:写入缓冲区

    构造方法摘要 

    BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。 

    BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。 

    方法摘要 

    void close() 关闭此流,但要先刷新它。 

    void flush() 刷新该流的缓冲。 

    void newLine() 写入一个行分隔符。具有跨平台性,相当于windows系统的" "和linux系统的" ";

    void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。 

    void write(int c) 写入单个字符。 

    void write(String s, int off, int len) 写入字符串的某一部分。 

    //例子4:
    import java.io.*;
    class BufferedWriterDemo
    {
        public static void main(String[] args) throws IOException
        {
            //创建一个字符写入流对象,和目的地文件相关联.
            FileWriter fw = new FileWriter("F:\myfile\buf.txt");
            
            //为了提高字符写入流效率,加入了缓冲技术,只需要将被提高效率的流对象作为参数
            //传递给缓冲区的构造函数即可。此时,缓冲区和流相关联.
            BufferedWriter buf = new BufferedWriter(fw);
            
            buf.write("abcdefg");
            for(int i=0;i<3;i++)
            {
            buf.newLine();//换行
            buf.write("changjiang"+i);
            //记住,只要用到缓冲区,必须要刷新
            buf.flush();        
            }
            //其实关闭缓冲区,就是关闭缓冲区中的流对象
            buf.close();
        }
    }
    使用字符流缓冲的一个综合实例如下:
    要求:通过一个缓冲区复制一个.java文件
    注意:readLine()方法返回的时候只返回回车符之前的数据内容,并不返回回车符。
    //例子5: 没有异常处理时:
    import java.io.*;
    class BufferedCopyTest
    {
        public static void main(String[] args)throws IOException
        {
            //创建一个读入流对象,与要被复制的文件相关联
            FileReader fr = new FileReader("BufferedReaderDemo.java");
            //创建一个写入流对象,与目的文件相关联
            FileWriter fw = new FileWriter("BufferedReaderDemo_Copy.txt");
            
            //创建一个读入缓冲区,与流对象相关联
            BufferedReader bufr = new BufferedReader(fr);
            //创建一个写入缓冲区,与流对象相关联
            BufferedWriter bufw = new BufferedWriter(fw);        
            
            //读取数据存入缓冲区中
            String line;
            while((line = bufr.readLine())!=null)
            {
                bufw.write(line);
                bufw.newLine();
                bufw.flush();
            }
            bufw.close();
            bufr.close();
        }
    }
    //例子6: 有异常的处理时:
    import java.io.*;
    class BufferedCopyTest2
    {
        public static void main(String[] args)
        {
            BufferedReader bufr = null;
            BufferedWriter bufw = null;
            try
            {
             bufr = new BufferedReader(new FileReader("BufferedReaderDemo.java"));
             bufw = new BufferedWriter(new FileWriter("BufferedReader_Copy.txt"));                
             String line;
              while((line = bufr.readLine())!=null)
              {
                System.out.println(line);  
                bufw.write(line);
                bufw.newLine();
                bufw.flush();
              }
            }
            catch(IOException e)
            {
                throw new RuntimeException("读写入异常");
            }
            finally
            {
              try
              { 
                if(bufr!=null)
                   bufr.close();                  
              }    
              catch(IOException e)
              {
                throw new RuntimeException("关闭流异常");  
              }
              try
              { 
                if(bufw!=null)
                   bufw.close();                  
              }    
              catch(IOException e)
              {
                throw new RuntimeException("关闭流异常");  
              }
            }
        }
    }
     
  • 相关阅读:
    解决phpcms图片太大撑破表格图片自适应图片按比例缩小
    CSS代码使纯英文数字自动换行
    CSS网页布局错位:CSS宽度计算
    CSS控制div宽度最大宽度/高度和最小宽度/高度
    鼠标HOVER时区块动画旋转变色的CSS3样式掩码
    记录--正则表达式
    写在前面
    ruby Mixin用法
    ruby 模块 的引入
    ruby 编写迭代器
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4917994.html
Copyright © 2020-2023  润新知