黑马程序员技术交流社区
标题: 老毕写错了!!!!io流MyBufferedReaderDemo [打印本页]
作者: ysdolls 时间: 2014-8-5 23:30
标题: 老毕写错了!!!!io流MyBufferedReaderDemo
本帖最后由 ysdolls 于 2014-8-8 08:55 编辑
老毕写错了?io流MyBufferedReaderDemo 第19天 第五个视频12分20秒运行的程序
看的时候就感觉输出应该重复了 readline应该是调用一次读一行 如读取数据为:
abcd1
abcd2
abcd3
则调用三次readline 不加换行的话输出应为:
abcd1abcd2abcd3
加了就和读取的一样
老毕视频里也确实对了,和读取内容一样是三行,可发出来的源代码运行后却不是这样输出的 如下:
asdk1
asdk1asdk2
asdk1asdk2asdk3
asdk1asdk2asdk3asdk4
asdk1asdk2asdk3asdk4asdk5
因为每次读数据都没清空StringBuilder 所以每次输出都带着之前所有读过的 虽然源代码老毕进行了 继承 重写代码的完善 可主要功能部分没有变,为何视频里输出正确,而相同代码再运行却出现了这样的情况呢?
有大神能来分析一下 数据读取的过程嘛?总结问题如下:
1.我不明白了,StringBuilder是在方法里定义的,应该每次调用 都new了一个StringBuilder,都是不同的StringBuilder,可为什么输出的sb一直带有之前读取的?
2.sun的readLine是一个数组一个数组的读一行数据到内存中。然后write方法通过write调用flush()方法将内存中的数据存入文件。而老毕的是一个字符一个字符的读到内存中来凑够一行。根本和直接调用read方法是一样的,重写readline没有了意义。
3.我看了一下String line 每次指向的字符串如下:
asdk1
asdk1asdk2
asdk1asdk2asdk3
asdk1asdk2asdk3asdk4
asdk1asdk2asdk3asdk4asdk5
所以 String line 每次被赋予的字符串就是 方法每次被调用返回的字符串。很明显 方法内部 的StringBuilder sb =new StringBuilder();每次都是一个对象没有新的引用覆盖。
请大神详细讲解数据的流向内存的步骤,学了一天 脑袋有点迷糊。
我用的是去深圳黑马领导的光盘里的内容 粘贴出程序如下:
- /*
- 明白了BufferedReader类中特有方法readLine的原理后,
- 可以自定义一个类中包含一个功能和readLine一致的方法。
- 来模拟一下BufferedReader
- */
- import java.io.*;
- class MyBufferedReader extends Reader
- {
-
- private Reader r;
- MyBufferedReader(Reader r)
- {
- this.r = r;
- }
- //可以一次读一行数据的方法。
- public String myReadLine()throws IOException
- {
- //定义一个临时容器。原BufferReader封装的是字符数组。
- //为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。
- StringBuilder sb = new StringBuilder();
- int ch = 0;
- while((ch=r.read())!=-1)
- {
- if(ch=='\r')
- continue;
- if(ch=='\n')
- 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.read(cbuf,off,len) ;
- }
- public void close()throws IOException
- {
- r.close();
- }
- public void myClose()throws IOException
- {
- r.close();
- }
- }
- class MyBufferedReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- FileReader fr = new FileReader("buf.txt");
- MyBufferedReader myBuf = new MyBufferedReader(fr);
- String line = null;
- while((line=myBuf.myReadLine())!=null)
- {
- System.out.println(line);
- }
- myBuf.myClose();
- }
- }
复制代码
作者: 闪电博尔特 时间: 2014-8-5 23:40
好像是吧
作者: ysdolls 时间: 2014-8-5 23:42
好像是什么。。。我不明白老毕那个程序为什么输出对了,我明明运行的是原装的程序啊
作者: masai158 时间: 2014-8-5 23:44
本帖最后由 masai158 于 2014-8-5 23:45 编辑
StingBuilder 写入的时候,还记得写一个换行符。
我之前做了一个题,就是将一个文件的内容反转过来。然后在反转回去。。这里如果简单的写换行符的话会出问题。我先留个标记。明天去公司在上代码看看
作者: masai158 时间: 2014-8-5 23:52
no。你肯定不对。你肯定写错了。好好看看
作者: masai158 时间: 2014-8-5 23:55
本帖最后由 masai158 于 2014-8-5 23:57 编辑
你每写出一次。记得将缓冲区清空吧sb.delete(0,sb.length())
作者: ysdolls 时间: 2014-8-6 07:37
老毕就没有清,为什么他的运行对了?我俩的是一样的程序
作者: 沐小北 时间: 2014-8-6 07:53
有时候我也觉得老毕写错了,为什么他的可以运行,我的却不可以,到最后才发现原来是我的其他位置不是字母错了,就是字符错了,细心就会发现的。
作者: masai158 时间: 2014-8-6 08:09
asdk1
asdk1asdk2
asdk1asdk2asdk3
asdk1asdk2asdk3asdk4
asdk1asdk2asdk3asdk4asdk5
每次都出现上一次。肯定是你没有清。我记得老毕第一次 是没有清就是为了演示这个问题。然后最后清了就正常了。你清添加清楚?正常吗?
作者: masai158 时间: 2014-8-6 08:11
- /**将一个文件中的内容倒序(不允许用第二个文件)*/
- import java.io.*;
- import java.util.*;
- class Test6
- {
- public static void main(String[] args) throws IOException
- {
- String fileName = "Test6.txt";
- ArrayList<String> al = new ArrayList<String>();//使用一个容器来装每一段数据
- File fr = new File(fileName);
- fileToSb(fr,al); //将读取的到文件每一段数据都读到集合中
- alToFile(al,new File(fileName)); //将集合的每一段数据写到文件中
- }
- public static void fileToSb(File fr,ArrayList<String> al) throws IOException
- {
- BufferedReader bufr =new BufferedReader(new FileReader(fr));
-
- String flag ;
- while((flag=bufr.readLine())!=null)
- {
- al.add(flag); //将每一行读取的信息保存到集合中
- }
- bufr.close();
- }
- public static void alToFile(ArrayList<String> al,File fw) throws IOException
- {
- fw.delete(); //将源文件删掉
- BufferedWriter bufw = new BufferedWriter(new FileWriter(fw)); //创建一个文件
- for(int end=al.size()-1; end>=0; end--)
- {
- bufw.write(al.get(end).toString());
- bufw.newLine();
- }
- bufw.close();
- }
- }
- 希望能帮助你
复制代码
作者: ysdolls 时间: 2014-8-6 09:32
这个是复制老毕的代码。。。而且运行是成功的,只是结果不同
加一句 read没有flush方法,因为read不需要写入数据
作者: ysdolls 时间: 2014-8-6 09:33
本帖最后由 ysdolls 于 2014-8-6 09:40 编辑
你记错了,我又重新看了一次,他确实没请,老毕也没演示过什么第一次没清,第二次清了,他倒是演示过newLine 和print_ln而且 为什么 这个程序没清 却可以结束? 不清不是sb里一直有数据?
asdk1
asdk1asdk2
asdk1asdk2asdk3
1.每次输出都带有之前的内容,所以每次调用MyReadLine都带有之前的数据
2.sb始终没清,那代表sb里始终有内容,而程序却可以结束,只有当返回null的时候才会结束while循环,而if(sb!=null)的话则一直有返回值,程序是怎么结束的呢?
3如果sb是每次调用MyReadLine都新建引用(也就是都清空),那应该是每次MyReadLine每次被调用,read()方法都是从文件最开始开始读,那他是怎么跳过if \r\n来返回两行如:asdk1asdk2,甚至3行的数据呢?
作者: fantacyleo 时间: 2014-8-6 10:58
我也记得他演示过错误的情况。。。我是看他写之前就自己写了一遍,我注意到了要清空的情况,所以写完之后看他第一次写没清就想他肯定要出错了,果不其然,后来他改过来了。
作者: 200米王朝 时间: 2014-8-6 11:03
老毕的视频中有一些错别字,但这都不是事
主要是跟着听就明白,那些错别字或者代码小错误大家明白就好了
高效率的打字难免有手误
作者: 渴望学习 时间: 2014-8-6 11:15
路过~~
作者: masai158 时间: 2014-8-6 11:16
没有清的话。我又回忆起了。好像他又new了一个 sb。。
作者: ysdolls 时间: 2014-8-6 12:47
是我打开方式不对了吗。。。QAQ
作者: ysdolls 时间: 2014-8-6 17:43
谁来讲解一下呀?为什么程序是这样输出的?
作者: sunny~ 时间: 2014-8-6 23:35
路过,顶一帖
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |