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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 随风而去 中级黑马   /  2014-5-4 11:29  /  2257 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天想自己写个缓冲流玩下,当写的时候发现困难重重
最难点是你要自己实现一个缓冲池用来存放数据
而你取数据的时候是只能从缓冲池中去取出数据
缓冲的数据是纯入内存当中,这样读取缓冲数据的时候会大大提高效率
有木有大神实现了一个IO缓冲流  最主要是要实现了缓冲池的实现
求助------下面这个是我自己实现的缓冲字符流 但是只实现了readline方法
  1. package test2;

  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.Reader;

  6. /**
  7. * 自定义缓冲字符流
  8. * 难点: 如果要实现一个类似缓冲流的缓冲区  这个问题还没想透彻
  9. * @author 李昂志
  10. */
  11. public class MyBufferedReader extends Reader{
  12.         private static int bufferdSize = 9999;   //字符缓冲区原始数据量大小
  13.         private Reader in = null;
  14.         private char[] cs;  //用来存储字符缓冲的数据
  15.        
  16.         /**
  17.          * 自定义的缓冲池
  18.          * @param in
  19.          * @param size
  20.          */
  21.         public MyBufferedReader(Reader in , int size){
  22.                 super(in);
  23.                 if(size<=0){
  24.                         throw new IllegalArgumentException("Buffer size <= 0");
  25.                 }
  26.                 MyBufferedReader.bufferdSize = size;
  27.                 this.in = in;
  28.         }
  29.         /**
  30.          * 使用默认的缓冲池
  31.          * @param in
  32.          */
  33.         public MyBufferedReader(Reader in){
  34.                 this(in,bufferdSize);
  35.         }
  36.         /**
  37.          * 此方法空实现,这个地方读取要去读取缓存池,无解中
  38.          */
  39.         @Override
  40.         public int read(char[] cbuf, int off, int len) throws IOException {
  41.                
  42.                 return in.read(cbuf, off, len);
  43.         }
  44.         /**
  45.          * 读取一行文本 ,读到换行处则 退出
  46.          * 因为只要读取一行数据,一行数据的数据量一般较小 所以对缓冲池的要求不高 这里是模仿了老师的 完善了一点而已
  47.          * @return 读取一行的文本 字符串
  48.          * @throws IOException
  49.          */
  50.         public String readline() throws IOException{
  51.                 StringBuilder sb = null;
  52.                 char c ='A';
  53.                 if(cs == null) cs = new char[bufferdSize];
  54.                
  55.                 int i,j =0;
  56.                 while((i = in.read()) != -1){
  57.                         if(sb == null){
  58.                                 sb = new StringBuilder();
  59.                         }
  60.                         c = (char) i;
  61.                         if ( c == '\r') continue;
  62.                         if ( c == '\n') break;
  63.                         cs[j++] = c;
  64.                 }
  65.                 if(sb != null ) sb.append(cs ,0 ,j);
  66.                 else return null;
  67.                 return sb.toString();
  68.         }
  69.         /**
  70.          * 获取缓冲池大小
  71.          * @return
  72.          */
  73.         public int getBufferdSize() {
  74.                 return bufferdSize;
  75.         }
  76.         @Override
  77.         public void close() throws IOException {
  78.                 // TODO Auto-generated method stub
  79.                 if(in != null){
  80.                         in.close();
  81.                 }
  82.         }
  83.         public static void main(String[] args) throws IOException {
  84.                 System.out.println("----");
  85.                 MyBufferedReader in = new MyBufferedReader(new FileReader("abc.txt"));
  86.                 String s = null;
  87.                 while((s = in.readline())!= null){
  88.                         System.out.println(s);
  89.                 }
  90.                 in.close();
  91.         }
  92. }
复制代码



评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

6 个回复

倒序浏览
实际上所谓的缓冲,只不过是一个字节数组而已,或者对于Reader来说也可以用StringBuffer来缓冲
  1. import java.io.IOException;
  2. import java.io.Reader;

  3. public class MyBufferedReader {
  4.         private Reader r;
  5. //        记录读取的行数
  6.         private int len=0;
  7. //        构造时要传入一个Reader对象
  8.         MyBufferedReader(Reader r)
  9.         {
  10.                 this.r=r;
  11.         }
  12.         public int getLen() {
  13.                 return len;
  14.         }
  15.         public void setLen(int len) {
  16.                 this.len = len;
  17.         }
  18.         public String myReadLine() throws IOException
  19.         {
  20. //                在这里也可以用StringBuffer 进行存储
  21.                 String str ="";
  22.                 int c=0;
  23.        
  24.                 len++;
  25.                 while((c=r.read())!=-1)
  26.                 {
  27.                        
  28.                         if(c=='\r')
  29.                                 continue;
  30.                         if(c=='\n')
  31.                                 break;
  32.                         str+=(char)c;
  33.                 }
  34.                 if(str=="")
  35.                         return null;
  36.                 return str;
  37.         }
  38.         public void close() throws IOException
  39.         {
  40.                 r.close();
  41.         }
  42. }
复制代码
回复 使用道具 举报
本帖最后由 随风而去 于 2014-5-4 15:55 编辑
fei_xiong 发表于 2014-5-4 14:24
实际上所谓的缓冲,只不过是一个字节数组而已,或者对于Reader来说也可以用StringBuffer来缓冲
...

你这个和我的有区别么,在读取效率上恐怕比我的还低,并且你这个方法应该还存在很多问题,你读取文件看试试会不会报错..
而我所考虑的主要问题是要实现 缓冲池的实现
我们都知道 缓冲流的原理是  我们所拿到的数据是重缓冲区(也就是缓冲池)里面所获取的,你获取缓冲区的数据同时要用下标跟新,同时要保证数据的正确性.    你这个len 在这里没有任何意义

回复 使用道具 举报
随风而去 发表于 2014-5-4 15:49
你这个和我的有区别么,在读取效率上恐怕比我的还低,并且你这个方法应该还存在很多问题,你读取文件看试 ...

感觉你写的程序没有什么问题啊!
int read(CharBuffer target)  可以直接读入的字符缓冲区!
不知道你还想实现什么功能!
回复 使用道具 举报
ò壞尛孩 发表于 2014-5-4 17:05
感觉你写的程序没有什么问题啊!
int read(CharBuffer target)  可以直接读入的字符缓冲区!
不知道你还 ...

其实说是自定义缓存流,可其实我并没有实现缓冲流的操作
我这个数据并没有存取到内存中,基本上是每读取一次数据
就要重新去读取一次,而如果是缓冲流 ,则直接去一个已经读取好数据里面的池子里面去读取
就好如 readline 是去重内存中去读取数据 , 而不是直接去读文本的数据
这个readline 方法 它的操作实际是这样子
文件流--- >读取文件一行(这行文件并没有存入到内存中) ---> 得到这行数据
而我想要的功能是这样子 文件流---> 读取到缓存池中 --->用 readline方法  从缓冲区读取数据 ----> 用户得到数据
回复 使用道具 举报
随风而去 发表于 2014-5-4 17:24
其实说是自定义缓存流,可其实我并没有实现缓冲流的操作
我这个数据并没有存取到内存中,基本上是每读取 ...

你可以在readLine里面加个标记!用来记录 读取的字符长度,下次调用的时候从上次结束的位置读取
abstract  int read(char[] cbuf, int off, int len)
          将字符读入数组的某一部分。
实现这个抽象方法!思路告诉你了!
回复 使用道具 举报
ò壞尛孩 发表于 2014-5-4 17:30
你可以在readLine里面加个标记!用来记录 读取的字符长度,下次调用的时候从上次结束的位置读取
abstract  ...

呵呵,其实原理我都知道,但是实现出来有一定的困难,我看了Buffered的源代码
表示真心困难...
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马