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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小黑子 中级黑马   /  2014-9-22 07:59  /  1716 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小黑子 于 2014-9-22 19:21 编辑

看毕老师的视频,写了一个MyBufferedReader的练习。其主要目的是模拟一下BufferedReader中的readLine方法。问题是:
             主函数中
                              while((str=mbr.myReadLine())!=null)                              {
                                       System.out.println(str);
                               }
其中,每一次调用myReadLine(),调用完毕就会释放myReadLine()运行时所占用的内存。那么这又如何保证下一次调用myReadLine()时,是接着上一次调用的的位置继续读取(也就是读取下一行),而不是永远在读第一行呢?

  1. class MyBufferedReader
  2. {
  3.         FileReader fr;
  4.         MyBufferedReader(FileReader fr)
  5.         {
  6.                 this.fr = fr;
  7.         }
  8.         public String myReadLine() throws IOException
  9.         {
  10.                 int ch;
  11.                 StringBuilder sb = new StringBuilder();
  12.                 while((ch=fr.read())!=-1)
  13.                 {
  14.                         if(ch=='\r')
  15.                                 continue;
  16.                         if(ch=='\n')
  17.                                 return sb.toString();
  18.                         else
  19.                         sb.append((char)ch);
  20.                 }

  21.                 //当文件末尾没有回车时
  22.                 if(sb.length()!=0)
  23.                         return sb.toString();
  24.                 return null;
  25.         }
  26.         public void myNewLine()
  27.         {
  28.                 System.out.println();
  29.         }
  30.         public void myClose() throws IOException
  31.         {
  32.                 fr.close();
  33.         }
  34. }

  35. class MyBufferedReaderDemo
  36. {
  37.         public static void main(String[] args) throws IOException
  38.         {
  39.                 FileReader fr = null;
  40.                 MyBufferedReader mbr = null;
  41.                 try
  42.                 {
  43.                         fr = new FileReader("BufferedReaderDemo.java");
  44.                         mbr = new MyBufferedReader(fr);
  45.                         String str = null;
  46.                         while((str=mbr.myReadLine())!=null)
  47.                         {
  48.                                 System.out.println(str);
  49.                         }
  50.                 }
  51.                 catch (IOException e)
  52.                 {
  53.                         throw new IOException(e.toString());
  54.                 }
  55.                 finally
  56.                 {
  57.                         try
  58.                         {
  59.                                 mbr.myClose();
  60.                         }
  61.                         catch (IOException e)
  62.                         {
  63.                                 throw new IOException(e.toString());
  64.                         }
  65.                 }
  66.         }
  67. }
复制代码




13 个回复

倒序浏览
“每一次调用myReadLine(),调用完毕就会释放myReadLine()运行时所占用的内存” 这句话怎么说?
回复 使用道具 举报
本帖最后由 JerryJava 于 2014-9-22 12:01 编辑
  1. package IOEx;
  2. import java.io.*;
  3. public class jerryTest01 {
  4.         public static void main(String[] args) throws IOException {
  5.                 FileReader fr = new FileReader("c:\\JerryDemo.txt");
  6.                
  7.                 int len1 = 0;
  8.                
  9.                 while(true)
  10.                 {
  11.                         if(fr.read()=='4')
  12.                                 break;
  13.                 }
  14.                 char next = (char)(fr.read());
  15.                 System.out.println("next="+next);
  16.                
  17.                
  18.         }
  19. }
复制代码

其实需要理解Reader基类中的read() 方法,问题集中在什么情况会使read()停止,API中原文如下
  • readpublic int read()         throws IOExceptionReads a single character. This method will block until a character is available, an I/O error occurs, or the end of the stream is reached. Subclasses that intend to support efficient single-character input should override this method.

    Returns: The character read, as an integer in the range 0 to 65535 (0x00-0xffff), or -1 if the end of the stream has been reached Throws: IOException - If an I/O error occurs有3中方式 会被block第一:返回了指定的字符 第二:IO异常第三:整个流的结束!即返回了-1 , 常用来做循环的判断(注意,不是行的结束。 \r\n也是字符,只不过被转义了。)
    所以,结论挺明显了,读一下我为你写的实例就知道了,我的JerryDemo中内容如下1234567890第一次循环找到了4,然后break , 下一次fr.read()的值赋给了next并打印,结果是5.也就是说只要读取流没有关闭,它的read()方法会在block处继续读,当然如果有异常或者读到了最后就读不了了~希望对你有帮助。

回复 使用道具 举报
格式有点乱了,sorry,能看懂就好了。:'(
回复 使用道具 举报
fantacyleo 发表于 2014-9-22 11:22
“每一次调用myReadLine(),调用完毕就会释放myReadLine()运行时所占用的内存” 这句话怎么说? ...

Leo哥,帮我看一下这样分析对吗。谢了。
回复 使用道具 举报
通过角标控制的
回复 使用道具 举报
JerryJava 发表于 2014-9-22 11:58
其实需要理解Reader基类中的read() 方法,问题集中在什么情况会使read()停止,API中原文如下
  • readpub ...

  • 嗯,对,readLine方法的实现基础是read方法。可以想象有一个指针,每read一次,就指向下一个字节(字节流)或字符(字符流)。这样无论读到哪里,下一次读取时都能从当前位置往下读。我记得老毕的视频里有带着大家写一个模拟readLine的程序,把那个程序搞明白也就清楚readLine的原理了
    回复 使用道具 举报
    郑飞 高级黑马 2014-9-22 18:15:57
    8#
    read好像是native方法了吧 想知道为啥会顺序一直的读下去只能看源码了 因为也只是看视频知道表面现象{:2_32:}
    回复 使用道具 举报
    JerryJava 发表于 2014-9-22 11:58
    其实需要理解Reader基类中的read() 方法,问题集中在什么情况会使read()停止,API中原文如下
  • readpub ...

  • 看得不是很明白,不过也差不多了,谢谢哈。
    回复 使用道具 举报
    fantacyleo 发表于 2014-9-22 16:08
    嗯,对,readLine方法的实现基础是read方法。可以想象有一个指针,每read一次,就指向下一个字节(字节流 ...

    嗯,差不多了,我再参悟参悟。3Q~~
    回复 使用道具 举报
    对人类来说是一行 ... 对计算机来说就是一个换行符的问题..  它就是从头到尾读
    回复 使用道具 举报
    fantacyleo 发表于 2014-9-22 11:22
    “每一次调用myReadLine(),调用完毕就会释放myReadLine()运行时所占用的内存” 这句话怎么说? ...

    还是有点疑惑。。。再过来请教一下。
    这句话的意思是:
        while循环中不是每次都要调用myReadLine()么?要调用myReadLine(),那么就需要将myReadLine()方法加载进内存,这没问题吧?
        我理解的是,while的每一次循环开始时,将myReadLine()加载进内存,然后在本次循环结束时,将myReadLine()所占内存释放。
        在下一次循环开始时,又将myReadLine()加载进内存,在这次循环结束时,再一次将myReadLine()所占内存释放。
       ……
       ……
       ……
      如此循环,直到while结束。

    不知道我理解的对不对???
    回复 使用道具 举报
    小黑子 发表于 2014-9-22 20:56
    还是有点疑惑。。。再过来请教一下。
    这句话的意思是:
        while循环中不是每次都要调用myReadLine()么 ...

    这个理解大致上没问题。但readLine方法执行完毕从栈内存中被清除并不会导致上一次读取的位置丢失。Reader对象中保存有当前读到文件哪个位置的状态变量,read和readLine方法的调用会改变对象的状态,改变的效果并不会因为方法执行完毕而丢失
    回复 使用道具 举报
    fantacyleo 发表于 2014-9-22 21:03
    这个理解大致上没问题。但readLine方法执行完毕从栈内存中被清除并不会导致上一次读取的位置丢失。Reader ...

    SOGa,谢谢啦!
    回复 使用道具 举报
    您需要登录后才可以回帖 登录 | 加入黑马