java 的 clear 和 compact

##Buffer的基本用法
使用Buffer读写数据一般遵循以下四个步骤:

写入数据到Buffer
调用flip()方法
从Buffer中读取数据
调用clear()方法或者compact()方法

当向buffer写入数据时,buffer会记录下写了多少数据。一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式。在读模式下,可以读取之前写入到buffer的所有数据。

一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

下面两个例子就是两个方法的区别,compact()需要最后再循环一下,来保证数据被传输完,两个方法对比,即使compact()方法更节省一点,就向写写文章,在上次没写完的地方接着写,而clear()则会重新拿一张新的只开始写

下面的例子是网上找的,我自己有一些疑问channelCopy1 中为什么会存在部分读取的情况,每次 dest.write(buffer);不是都会读取完数据完 从 src中写入的数据吗?应该不会有没读取完的数据啊?

	package com.unis.io;
		
		import java.io.IOException;
		import java.nio.ByteBuffer;
		import java.nio.channels.Channels;
		import java.nio.channels.ReadableByteChannel;
		import java.nio.channels.WritableByteChannel;
		
		public class channelTest {
		
		    public static void main(String[] args) throws IOException {
		        ReadableByteChannel source = Channels.newChannel(System.in);
		        WritableByteChannel dest = Channels.newChannel(System.out);
		        channelCopy1(source, dest);
		        // alternatively, call channelCopy2 (source, dest);
		        System.out.println(100);
		        source.close();
		        dest.close();
		    }
		
		    /**
		     * Channel copy method 1. This method copies data from the src
		     * channel and writes it to the dest channel until EOF on src.
		     * This implementation makes use of compact( ) on the temp buffer * to pack down the data if the buffer wasn't fully drained. This * may result in data copying, but minimizes system calls. It also * requires a cleanup loop to make sure all the data gets sent.
		     */
		    private static void channelCopy1(ReadableByteChannel src,
		                                     WritableByteChannel dest)
		            throws IOException {
		        ByteBuffer buffer = ByteBuffer.allocateDirect(3 );
		        while (src.read(buffer) != -1) {
		            // Prepare the buffer to be drained
		            buffer.flip();
		            // Write to the channel; may block
		            dest.write(buffer);
		            // If partial transfer, shift remainder down
		            // If buffer is empty, same as doing clear( )
		            buffer.compact();
		        }
		// EOF will leave buffer in fill state
		        buffer.flip();
		// Make sure that the buffer is fully drained
		        while (buffer.hasRemaining()) {
		            dest.write(buffer);
		        }
		    }
		
		    /**
		     * Channel copy method 2. This method performs the same copy, but
		     * assures the temp buffer is empty before reading more data. This
		     * never requires data copying but may result in more systems calls.
		     * No post-loop cleanup is needed because the buffer will be empty
		     * when the loop is exited.
		     */
		    private static void channelCopy2(ReadableByteChannel src,
		                                     WritableByteChannel dest)
		            throws IOException {
		        ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
		        while (src.read(buffer) != -1) {
		// Prepare the buffer to be drained
		            buffer.flip();
		// Make sure that the buffer was fully drained
		            while (buffer.hasRemaining()) {
		                dest.write(buffer);
		            }
		// Make the buffer empty, ready for filling
		            buffer.clear();
		        }
		    }
		}
		
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值