A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© luck_start 中级黑马   /  2015-10-5 12:28  /  663 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

6、 自定义字符输入流的包装类,通过这个包装类对底层字符输入流进行包装,
           让程序通过这个包装类读取某个文本文件(例如,一个java源文件)时,
           能够在读取的每行前面都加上有行号和冒号。
           
    思路:
    1.首先是字符的,输入的包装类,底层自然是一个一个读取字符.那么该
    包装类中必然要有read()方法.
    2.对于read()的数据如何让其具备一行一行的数据记录呢?必须要有一个
    变量,这个变量如何去定义,怎么样这个变量才会变化呢?
    3.每次一行的读取数据,那么可以在包装类中定义一个StringBuilder用来
    接受数据,当读到行末尾的时候,就返回这个StringBuilder的字符串.
   
  总结:
          1.java中读取的一行一行数据,也是依靠底层一个一个读取,然后根据\n来判断读取到行末尾,再一次性返回.
          2.对于判断结束标记,我们在自定义返回数据的时候,就需要给定一个可以让其结
          束的标记(null 或者 -1 等等).
          3.对于StringBuilder,其中接受的数据,并没用换行操作(因为底层中,一次一个字节读取,对于\r\n只是一个判断依据,并没有存储起来),因此我们需要手动,对于行结尾要添加"\r\n"以便输出时候识别换行.
         
  思考:
          java中,一次读取一行是提高了效率的操作.但是,一次读取一行其底层也是一个一个读取的操作.那么,怎么样能够证明,貌似一样的操作手法一次一行就效率更高呢?
         
          查阅api发现,如果没有定义缓冲区,每次读取后,都要将数据从字节转换成字符数据而后返回,这样会效率极低.
        个人认为:
        不管是字节流还是字符流,底层都是在读取字节.只是字符流加入了一个可以让我们识别的一个编码表.如果一次读一个字符,先存储起来,等到读到行末尾再一次输出.
        那么效率应该是提高在"数据返回"这个关键点上.而在底层读取啊,还有转换呀,
        这些方面是没有提高效率的.
* */
public class Demo06 {
        public static void main(String[] args) throws IOException {
                File fi = new File("c:\\stu.txt");
                String s = LineFile(fi);
               
                System.out.println(s);
        }

        public static String LineFile(File fi) throws IOException {
                MyLineReader mr = new MyLineReader(new FileReader(fi));
                String s = null;
                StringBuilder sb = new StringBuilder(); //为了让程序拥有自主控制输出,因此创建.
                mr.setLen(0);  //设置开始行号.
                while((s = mr.MyreadLine())!= null)
                {
                        sb.append( mr.getLen() + ":" + s + "\r\n");
                }
                return sb.toString(); //将数据返回,让客户拥有输出权利.
        }
}


class MyLineReader
{       
        private int len;  //自定义行数变量
        private Reader fi; //读取数据流.
        public MyLineReader(Reader fi)
        {
                this.fi = fi;
        }
        public String MyreadLine() throws IOException
        {
                len ++; //读取一行之后,len自增.
                StringBuilder sb = new StringBuilder(); //将数据存储起来.
                int i = 0;
                while((i = fi.read())!= -1)
                {
                        if(i == '\r')  
                                continue;
                        if(i == '\n') //当独到行标记时候,将数据全部返回.
                                return sb.toString();
                        sb.append((char)i); //没有到达行标记就继续读取.
                }
                if(sb.length() != 0) //StringBuilder的长度不为0,就继续返回数据.
                        return sb.toString();
                return null; //否则返回空.因为调用方法时候,是依靠返回是不是null来判断,是不是应该结束.
        }
        public int getLen() { //get,set方法,用来获取行号和设置行号.
                return len;
        }
        public void setLen(int len) {
                this.len = len;
        }       
}

1 个回复

倒序浏览
有些还没学到,不太懂
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马