java IO/NIO

Path

  • Path表示文件路径/文件
  • 创建方法
    • Paths的static方法//实际上底层调用了FileSystems.getDefault().getPath()方法
      • Path path = Paths.get(String first, String… more);
      • Path path = Paths.get(URI uri); //URI uri = URI.create(“C://ssssss”);
    • FIleSystems方法
      • Path path = FileSystems.getDefault().getPath(“C://ssss”);

I/O

  • 分类
    • 按操作方式
      这里写图片描述
    • 按操作对象
      这里写图片描述
  • 其他
    • File
      • 代表磁盘文件本身的对象
      • 构造方法:File(String pathName),pathName是文件路径
    • RandomAccessFile类
      • 是Object的子类
      • 随机访问:可以跳转到文件任意位置读写数据
      • 位置指示器:当前读写的位置
      • 构造方法RandomAccessFile(File file/String name, String mode)
      • mode
        • r:只读
        • rw:读写
        • rwd:读写,每次对文件内容的更新都写入底层存储设备
        • rws:读写,每次对文件内容/元数据的更新都写入底层存储设备
      • 用完需要close()

NI/O

  • Non-Blocking I/O, 面向缓冲,基于通道.通过内存映射文件(将文件的一段区域映射到内存中)
  • 三大组件

    • Buffer缓冲区

      • 本质上是一块内存区
      • 能发送基本类型(ByteBuffer/CharBuffer/ShortBuffer/IntBuffer/LongBuffer/FloatBuffer/DoubleBuffer)
      • 步骤

        • 数据写入buffer

          ByteBuffer buffer = ByteBuffer.allocate(1024);
          buffer.put("abc".getByte());
        • 调用flip

          buffer.flip();
        • 从buffer中读取数据

          char a = (char)buffer.get();
          char b = (char)buffer.get();
          char c = (char)buffer.get();
        • 调用buffer.clear()/buffer.compact()

          buffer.clear();
    方法描述
    buffer(int mark, int position, int limit, int capacity)记忆标志位,下一个读写位置,有效位数,容量
    mark()取当前的position快照标记mark
    position(int position)设置position的位置
    limit(int limit)如果position>limit,position=limit.如果mark>limit,重置mark
    reset()恢复position到先前标记的mark
    rewind()position=0,mark=-1.重写读取
    flip()limit=position,position=0,mark=-1.准备读取数据
    remaining()返回limit-position,返回还未读取的数据数
    clear()limit=capacity,position=0,mark=-1.清空数据(实际上没有,只是会覆盖)
    compact()将position到limit的数据前移,position=0,limit=limit-position.清空已读数据
    • Channel通道

      • 通道基于Buffer可以异步读写
      • FileChannel 文件 注:FIleChannel没有继承SelectableChannel,所以不能设置configureBlocking(false非阻塞).

        Path path = Paths.get("~/", "Download");
        FileChannel channel = FileChannel.open(path);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        int byteRead = channel.read(buffer);
        channel.close();
        
      • DatagramChannel UDP

        DatagramChannel channel = DatagramChannel.open();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //接收数据
        channel.bind(new InetSocketAddress(1234));
        channel.receive(buffer);
        //发送数据
        int send = channel.send(buffer, new InetSocketAddress("localhost", 1234));
        channel.close();
        
      • SocketChannel TCP

        SocketChannel channel = SocketChannel.open();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //接收数据
        channel.connect(new InetSocketAddress("127.0.0.1", 3333));
        channel.read(buffer);
        //发送数据
        channel.write(buffer);
        
        channel.close();
        
      • ServerSocketChannel 监听TCP,一个请求一个

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 3333));
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        SocketChannel channel = serverSocketChannel.accept();
        //接收数据
        channel.read(buffer);
        //发送数据
        channel.write(buffer);
        serverSocketChannel.close();
        channel.close();
        
      • AsynchronousFileChannel 异步文件通道 java7增加的异步文件读写(了解一下, 不知道与AIO有什么关系)

        //读
        AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardpenOption.READ);
        //用Future接受数据
        Future<Integer> future = channel.read(buffer, position);
        //用CompletionHandler接受数据
        channel.read(buffer, position,  buffer, new CompletionHandler<Integer, ByteBuffer>)
        
        //写
        AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardpenOption.WRITE);
        //用Future接受数据
        Future<Integer> future = channel.write(buffer, position);
        //用CompletionHandler接受数据
        channel.write(buffer, position,  buffer, new CompletionHandler<Integer, ByteBuffer>)
    • Scatter/Gather

      • 本地矢量I/O
      • 可以对多个Buffer进行操作
      • Scatter: 从一个Channel中读取数据按顺序分散到多个Buffer(就是一个Buffer[])中
      • Gather: 将多个Buffer(就是一个Buffer[])中的数据按顺序发送到一个Channel中
    • 通道间通讯
      • transferFrom(ReadableByteChannel src, long position, long count)从其他到自己
      • transferTo(long position, long count, WritableByteChannel target)从自己到目标
  • Selector选择器

    • 亦称多路复用器
    • 检查n个Chnnel是否处于可读/可写,从而实现单线程管理多个Channel
    • 使用

      ServerSockerChannel sschannel = ServerSocketChannel.open();
      ssc.socket().bind(new InetSocketAddress("127.0.0.1", "3333");
      //选择器操作
      sschannel.configureBlocking(false);//abstract SelectableChannel configureBlocking(boolean block)
      Selector selector = Selector.open();
      sschannel.register(selector, SelectionKey.OP_READ);//这里可以接收一个SelectionKey的返回值
      
      while(true) {
          Set<SelectionKey> selectedKeys = selector.selectedKeys();
          Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
          while (keyIterator.hasNext()) {
              SelectionKey key = keyIterator.next();
              keyIterator.remove();
              if (key.isAcceptable()) {
                  SockerChannel channel = sschannel.accept();
                  channel.configureBlocking(false);
                  channel.register(selector, SelectionKey.OP_READ);
              } else if (key.isConnectable) {
                  //...
              } else if (key.isReadable) {
                  SocketChannel channel = (SocketChannel)key.channel();
                  readBuffer.clear();
                  channel.read(readBuffer);
                  key.interestOps(SelectionKey.OP_WRITE);
              } else if (key.isWritable) {
                  SocketChannel channel = (SocketChannel)key.channel();
                  channel.write(writeBuffer);
                  key.interestOps(SelectionKey.OP_READ);
              }
              keyIterator.remove();
          }
      }
      
    • register()第二个参数是”interest集合”(注意是集合可以不止一个),channel对4种时间感兴趣

      • Connect->SelectionKey.OP_CONNECT
      • Accept->SelectionKey.OP_ACCEPT
      • Read->SelectionKey.OP_READ
      • Write->SelectionKey.OP_WRITE
    • SelectionKey
      • 表示一个特定的Channel与一个特定的Selector之间的注册关系
      • 方法
    方法描述
    attachment()返回attachment,attachment可以在注册时指定
    channel()返回对应的channel
    selector()返回对应的selector
    int interestOps()返回事件,用返回值&Selectionkey.OP_XXX得到一个boolean值
    readyOps()返回已经准备就绪的操作的集合
    • 从Selector中选择channel(Selector维护三种SelectionKey集合)
      • Registered key set
      • Selected key set
      • Cancelled key set
    • 唤醒阻塞线程的方法
      • wakeup(): 使处于阻塞状态的select()理科返回该方法上第一个还没有返回的操作.若没有则下一个select()立刻调用
      • close(): 通过关闭Selector是任何一个阻塞线程都被唤醒,同时注册的channel都被注销.zhuxiao
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值