码迷,mamicode.com
首页 > 其他好文 > 详细

给你的流添加缓冲装置——字节块ByteChunk

时间:2015-04-05 17:29:34      阅读:1005      评论:0      收藏:0      [点我收藏+]

标签:java   tomcat   缓冲   bytechunk   charchunk   

这是一个很重要的一个字节数组处理缓冲工具,它封装了字节缓冲器及对字节缓冲区的操作,包括对缓冲区的写入、读取、扩展缓冲区大小等等,另外还提供相应字符编码的转码操作。此工具让缓冲操作变得更加方便,除了缓冲区他还有两个channel——ByteInputChannel和ByteOutputChannel,这两个通道一个用于输入读取数据,一个用于输出数据,并且会自动判断缓冲区是否超出规定的缓冲大小,一旦超出则把缓冲区数据全部输出。

技术分享

如上图,缓冲区buf负责存放待输出的字节数组,此区域有初始值及最大值,在运行时会根据实际进行扩充,一旦到达最大值则马上输出到指定目标。此外还定义了两个内部接口——ByteInputChannel和ByteOutputChannel,一般可以认为一个用于读取数据一个用于输出数据。另外它还包含Chartset对象,有了它可以方便转码工作。下面用一个简化例子说明字节块的工作机制,受篇幅影响,为使例子简洁这里省去了很多方法和Chartset对象,只展示缓冲的工作机制。

①   字节块ByteChunk的简洁实现,包含数据读取输出接口、内存分配方法allocate、缓冲区添加字节方法append、缓冲区扩容方法makeSpace及刷新缓冲区方法flushBuffer。

public final class ByteChunk {

       public static interface ByteInputChannel{

                public int realReadBytes(bytecbuf[], int off, int len)

                                   throwsIOException;

       }

       public static interface ByteOutputChannel{

                public void realWriteBytes(bytecbuf[], int off, int len)

                                   throwsIOException;

       }

 

       private byte[] buff;

       private int start = 0;

       private int end;

       private int limit = -1;

       private ByteInputChannel in = null;

       private ByteOutputChannel out = null;

 

       public ByteChunk() {

       }

 

       public void allocate(int initial, intlimit) {

                if (buff == null || buff.length< initial) {

                         buff = newbyte[initial];

                }

                this.limit = limit;

                start = 0;

                end = 0;

       }

       public void setByteInputChannel(ByteInputChannelin) {

                this.in = in;

       }

       public voidsetByteOutputChannel(ByteOutputChannel out) {

                this.out = out;

       }

       public void append(byte b) throwsIOException {

                makeSpace(1);

                if (limit > 0 && end>= limit) {

                         flushBuffer();

                }

                buff[end++]= b;

       }

       public void flushBuffer() throwsIOException {

                out.realWriteBytes(buff, start,end - start);

                end = start;

       }

       private void makeSpace(int count) {

                byte[] tmp = null;

                int newSize= buff.length * 2;

                if (limit > 0 &&newSize > limit) {

                         newSize = limit;

                }

                tmp = new byte[newSize];

                System.arraycopy(buff, start,tmp, 0, end - start);

                buff = tmp;

                tmp = null;

                end = end - start;

                start = 0;

       }

}

②   输出测试类OutputBuffer,此类使用字节块提供的缓冲机制对d盘的hello.txt文件进行写入操作,为更好说明缓冲区工作原理,把字节块的缓冲区初始大小设为3最大为7,我们要把八个字节码写到hello.txt文件,主要看加粗的三行代码,执行dowrite方法时因为长度为8,已经超过了缓冲区最大值,所以进行了一次真实写入操作,接着让程序睡眠十秒,期间你打开hello.txt文件只能看到7个字节数组,它们为1到7(使用十六进制打开)。十秒过后,由于执行了flush刷新操作才把剩下的一个字节写入文件。

public class OutputBuffer implements ByteChunk.ByteOutputChannel{

 

       private ByteChunk fileBuffer;

       FileOutputStream fileOutputStream;

 

       public OutputBuffer() {

                fileBuffer = new ByteChunk();

                fileBuffer.setByteOutputChannel(this);

                fileBuffer.allocate(3, 7);

                try {

                         fileOutputStream = newFileOutputStream("d:\\hello.txt");

                } catch (FileNotFoundExceptione) {

                         e.printStackTrace();

                }

       }

       public void realWriteBytes(byte cbuf[],int off, int len)

                         throws IOException {

                fileOutputStream.write(cbuf,off, len);

       }

       public void flush() throws IOException {

                fileBuffer.flushBuffer();

       }

       public int dowrite(byte[] bytes) throwsIOException {

                for (int i = 0; i <bytes.length; i++)

                         fileBuffer.append(bytes[i]);

                return bytes.length;

       }

       public static void main(String[] args)throws InterruptedException {

                OutputBuffer outputBuffer = newOutputBuffer();

                byte[] bytes = { 1, 2, 3, 4, 5,6, 7, 8 };

                try {

                         outputBuffer.dowrite(bytes);

                         Thread.currentThread().sleep(10*1000);

                         outputBuffer.flush();

                } catch (IOException e) {

                         e.printStackTrace();

                }

       }

}

 

字节块是一个很有用的工具类,它提供了缓冲工具方便我们对某些流添加缓冲区,类似的工具还有字符块CharChunk,顾名思义它是专门用为字符类型的数据提供缓冲操作。





喜欢研究java的同学可以交个朋友,下面是本人的微信号:

技术分享

给你的流添加缓冲装置——字节块ByteChunk

标签:java   tomcat   缓冲   bytechunk   charchunk   

原文地址:http://blog.csdn.net/wangyangzhizhou/article/details/44889139

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!