nio实例概述

主要就是两个概念:Channel Buffer

解释

  • 通道:给我的感觉就像c的fd句柄一样.
  • buffer:就是一个存储文件的缓冲区,这里值得注意的是它是有模式的,不是以前学习
  • c的那种buff就是一个简单的buffer
  • 选择器(selectors):一个选择器可以监听多个Channel,这个可以回去看看书上的Epoll
  • Scannter 一个Channel可以读取数据到多个Buffer当然,buffer是作为buffer的形式作为参数

nio是非阻塞的io

channel与Buffer实现

channel实现解释
FileChannel文件通道
datagramChanneludp通道
SocketChanneltcp通道
serverSocketChannel可以监听新进来的tcp连接,每个新连接创建一个SocketChannel

buffer解释
* ByteBuffer
* CharBuffer
* DoubleBuffer
* FloatBuffer
* IntBuffer
* LongBuffer
* ShortBuffer

下面是一个简单的实例路线如下

  • 先有个channel->b.txt的通道
  • 再有个buffer[]
  • channel读取数据到buffer
  • channel->a.txt的通道
  • buffer切换模式从写切换到读模式,不然获取写入到文件会一个数据也写不进去

把buffer写到channel->a.txt

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.Selector;

public class Gatter {
    public static void main(String[] argv){
        RandomAccessFile aFile = null;
        try {
            aFile = new RandomAccessFile("a.txt", "rw");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        FileChannel channel = aFile.getChannel();
        ByteBuffer[] buffArray = null;
        try {
            buffArray = getBuffArray();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //这里成功输出
        printByteArray(buffArray[0].array());
        System.out.println("---------------------------");
        System.out.println(buffArray[0].array().length);
        for(ByteBuffer byteBuffer : buffArray){
            byteBuffer.flip();           //Buffer有读和写两种模式  之前处于写模式
            //这里如果不做模式转换会出现写失败的情况
        }
        try {
            System.out.println(channel.write(buffArray));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(channel != null){
            try {
                channel.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static ByteBuffer[] getBuffArray() throws IOException{
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile("b.txt", "rw");

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //接口不能作为句柄     下面的代码就是Scantter的核心理念  居然不是语法而是类似于技巧
        FileChannel channel = randomAccessFile.getChannel();
        ByteBuffer buffer01 = ByteBuffer.allocate(1024);
        ByteBuffer buffer02 = ByteBuffer.allocate(1024);

        ByteBuffer[] buffArray = {buffer01 , buffer02};
        try {
            channel.read(buffArray);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //printByteArray(buffArray[1].array());
        if(channel != null){
            channel.close();
        }
        return buffArray ;
    }
    private static void printByteArray(byte[] arr){
        try {
            System.out.println(new String(arr , "utf-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

上面的例子也有更加简单的实现通过一个通道的transferFrom的方法来实现

函数说明:就是把参数里的channel的数据对拷到此channel中,当然这里只是简单测试了filechannel的

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class transferFrom {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile("a.txt", "rw");

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        FileChannel channel = randomAccessFile.getChannel();
        FileChannel toFileChannel = null;
        try {
            toFileChannel = getChannel();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            channel.transferFrom(toFileChannel, 0, toFileChannel.size());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(toFileChannel != null){
            try {
                toFileChannel.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(channel != null){
            try {
                channel.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static FileChannel getChannel() throws IOException{
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile("b.txt", "rw");

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //接口不能作为句柄     下面的代码就是Scantter的核心理念  居然不是语法而是类似于技巧
        FileChannel channel = randomAccessFile.getChannel();
        return channel ;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值