黑马程序员技术交流社区

标题: 自定义字节流缓冲区 [打印本页]

作者: 黑马连家华    时间: 2012-5-13 19:12
标题: 自定义字节流缓冲区
本帖最后由 Noword 于 2012-6-26 15:17 编辑

/*
自定义字节流的缓冲区
*/
import java.io.*;
class MyStreamBuffer
{
public static void main(String[] args) throws IOException
{
  //使用自定义字节读取流缓冲区关联文件
  MyBufferedInputStream mbis = new MyBufferedInputStream(new FileInputStream("F:\\My Documents\\My Music\\音乐\\月光奏鸣曲.mp3"));
  //定义一个字节写入流缓冲区
  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Documents and Settings\\LJH\\Desktop\\音乐2_Copy.mp3"));
  int b = 0;
  while ((b = mbis.myRead()) != -1)
  {
   bos.write(b);
  }
}
}
//自定义一个装饰类
class MyBufferedInputStream
{
//需要有一个字节文件输出流
private FileInputStream fis;
//定义一个记录字节缓冲区数据个数的变量
private int cou = 0;
//定义一个记录读取位置的指针
private int pos = 0;
//定义一个数组缓冲区,临时存放读取到的数组
private byte[] buffer = new byte[1024*3];
//定义一个构造函数,当初始化时,可以加载字节文件输出流
MyBufferedInputStream(FileInputStream fis)
{
  this.fis = fis;
}
//定义一个读取方法
public int myRead() throws IOException
{
  //当缓冲区中没有数据(cou==0)的时候,读取硬盘数据到buffer中
  if (cou == 0)
  {
   //使用cou记录读取到数据的个数
   cou = fis.read(buffer);
   //数据重新输出,所以指针归零
   pos = 0;
   return buffer[pos]&255;
   pos++;//提示:error: unreachable statement       pos++;
   cou--;
  }
  //当缓冲区中有数据时,继续输出
  if (cou > 0)
  {
   return buffer[pos]&255;
   pos++;//提示同上
   cou--;
  }
  return -1;
}
}
//求解决方案
作者: 魏涞    时间: 2012-5-13 19:40
你都return了,当然执行不了下面的语句。
作者: 赵玮_Tom    时间: 2012-5-13 19:40
本帖最后由 赵玮_Tom 于 2012-5-13 19:45 编辑

有一点必须明确:当方法中某条return语句100%可能被执行到的情况下,其后面不能再定义方法代码(不考虑try-catch-finally的情况)。所以报告错误。
解决方法:
return buffer[pos++]&255;
这样既能实现pos自增功能,又可以保证自增之前进行赋值。
作者: 黑马连家华    时间: 2012-5-13 20:25
魏涞 发表于 2012-5-13 19:40
你都return了,当然执行不了下面的语句。

嗯!谢谢
作者: 黑马连家华    时间: 2012-5-13 20:25
赵玮_Tom 发表于 2012-5-13 19:40
有一点必须明确:当方法中某条return语句100%可能被执行到的情况下,其后面不能再定义方法代码(不考虑try-c ...

嗯!谢谢啦
作者: 黑马连家华    时间: 2012-5-13 20:26
贴出正确代码
/*
自定义字节流的缓冲区
*/
import java.io.*;
class MyStreamBuffer
{
        public static void main(String[] args) throws IOException
        {
                //使用自定义字节读取流缓冲区关联文件
                MyBufferedInputStream mbis = new MyBufferedInputStream(new FileInputStream("F:\\My Documents\\My Music\\音乐\\月光奏鸣曲.mp3"));
                //定义一个字节写入流缓冲区
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Documents and Settings\\LJH\\Desktop\\音乐2_Copy.mp3"));
                int b = 0;
                while ((b = mbis.myRead()) != -1)
                {
                        bos.write(b);
                }
        }
}
//自定义一个装饰类
class MyBufferedInputStream
{
        //需要有一个字节文件输出流
        private FileInputStream fis;
        //定义一个记录字节缓冲区数据个数的变量
        private int cou = 0;
        //定义一个记录读取位置的指针
        private int pos = 0;
        //定义一个数组缓冲区,临时存放读取到的数组
        private byte[] buffer = new byte[1024*3];
        //定义一个构造函数,当初始化时,可以加载字节文件输出流
        MyBufferedInputStream(FileInputStream fis)
        {
                this.fis = fis;
        }
        //定义一个读取方法
        public int myRead() throws IOException
        {
                //当缓冲区中没有数据(cou==0)的时候,读取硬盘数据到buffer中
                if (cou == 0)
                {
                        //使用cou记录读取到数据的个数
                        cou = fis.read(buffer);
                        //数据重新输出,所以指针归零
                        pos = 0;
                        cou--;
                        return buffer[pos]&255;
                }
                //当缓冲区中有数据时,继续输出
                if (cou > 0)
                {
                        cou--;
                        return buffer[pos++]&255;
                }
                return -1;
        }
}

作者: 赵文杰    时间: 2012-5-13 22:42
            我也想了个自定义字节流
import java.io.IOException;
import java.io.InputStream;

/*
* 内部提供了一个缓冲区
* 当第一次调用read()方法时, 该类从被包装的流中读取一批字节装入缓冲区, 返回1个
* 以后再调用read()方法时, 就不从文件中读取了, 直接从缓冲区中返回
* 直到缓冲区中数据都被读取过之后, 才再次读取文件
*/
public class MyBufferedInputStream extends InputStream {
        private InputStream in;                                                // 引用被包装的对象
        private byte[] buffer = new byte[8192];                // 缓冲区
        private int pos;                                                        // 该返回缓冲区中的哪个索引
        private int len;                                                        // 缓冲区中有效数据的个数
       
        public MyBufferedInputStream(InputStream in) {                // 通过构造函数, 接收被包装的对象
                this.in = in;
        }
       
        public int read() throws IOException{
                if (pos == len) {                                // 第一次调用时pos和len都等于0, 所有数据都读取过时pos和len都等于数组中有效数据的个数
                        len = in.read(buffer);                // 使用被包装的流读取数据到缓冲区, 记住个数
                        pos = 0;                                        // pos归0, 从第一个开始返回
                }
                return len == -1 ? -1 : buffer[pos++] & 255;        // 如果遇到文件末尾, 就返回-1, 如果没遇到文件末尾, 从缓冲区中返回数据
        }
       
        public void close() throws IOException{
                in.close();                                                // 关闭被包装的流
                System.out.println("close in");
        }
}




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2