import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;public class FileCopy { public static String fff="C://Users/dell/Desktop/test.txt"; public static void main(String[] args) throws IOException { int bufSize=1024; byte[] bs=new byte[bufSize]; //分配一个新的字节缓冲区。 ByteBuffer bb = ByteBuffer.allocate(1024); //创建一个随机访问文件的实例,第一个参数是文件路径,第二个参数是文件的访问模式,r表示只读;getChannel方法表示获得一个与此文件 //相关联的通道对象,而通道的作用是用于读取、写入、映射和操作文件 FileChannel channel =new RandomAccessFile(fff, "r").getChannel(); //read方法将字节序列从此通道读入给定的缓冲区,从此通道的当前文件位置开始读取字节,然后根据实际读取的字节数更新该文件位置,参数为 //一个字节缓冲区,返回值为读取的字节数,可能为0,如果是读取到了文件的末尾,则返回为-1. while (channel.read(bb) != -1) { //ByteBuffer可以作为一个缓冲区,是因为它是内存中的一段连续的空间,在ByteBuffer对象内部定义了四个索引, //分别是mark,position,limit,capacity. //mark对当前position的标记,position表示当前可读写的指针,如果是向ByteBuffer对象中写入一个字节,那么就会向 //position所指向的地址写入这个字节;如果是从bytebuffer中读出一个字节,那么就会把position所指向的地址所在数据 //读出,读写完成之后,position的位置会加1. //flip方法将limit的值置为position的值,而把position置为0,在byteBuffer刚刚创建的时候,limit的 //值和容量的值是一致的,position的初始值为0,当读取了内容之后,position的位置为新读取内容的最后一个字节的位置。 //bb.flip(); int size = bb.position(); bb.rewind();//这个方法将position索引置为0,mark索引置为-1 bb.get(bs); // 把文件当字符串处理,直接打印做为一个例子。 System.out.print(new String(bs, 0, size)); bb.clear();//clear方法并没有将bytebuffer中的内容清空,它只是将postion设置为0,将limit设置为初始容量大小 //这样再往缓存中添加元素的时候,就会用新的元素来覆盖旧的元素,这样在最后一次读取流中的数据的时候,此缓冲区中的前面一段是新的内容 //而后面是旧的内容,以position为分界点。所以再输出缓冲区数据的时候需要当心将旧的内容再输出一次。 //解决办法有两种:一种是本例中的所使用的,每次都得到position的位置,以此为界限输出position之前的内容; //第二种是使用bb.compact(),这个方法的作用是,将byteBuffer中的没有读取完的数据剪切到byteBuffer中 //的最前面。 } }}