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
    评论
### 回答1: IO(输入输出)是指操作系统与硬件之间进行数据传输的过程。常见的IO操作包括读取和写入文件、网络数据传输等。 NIO (非阻塞IO)是Java中的一种IO编程方式,它支持非阻塞的数据传输,即程序在等待IO操作完成时不会阻塞。这样可以避免程序因等待IO而卡住的问题。NIO提供了异步通道、缓冲区等功能来支持高效的IO操作。 AIO (异步IO)是操作系统提供的另一种IO编程方式,它支持异步的数据传输。AIO允许程序在发起IO请求后立即返回,而不是等待IO操作完成。这样程序可以继续执行其他任务,避免因等待IO而阻塞。AIO在操作系统层面支持异步IO,而NIO是在Java语言层面支持异步IO. ### 回答2: IO,即Input/Output,是指计算机与外部设备之间进行数据传输的过程。传统的IO操作是同步的,即在进行IO操作时,程序会阻塞等待数据的读写完成。这种方式效率较低,因为程序在等待IO操作完成时无法做其他事情。 NIO,即New Input/Output,是Java在JDK1.4版本引入的一种新的IO模型。NIO可以实现非阻塞的IO操作,其核心是通过通道(Channel)和缓冲区(Buffer)来实现数据的读写。NIO通过选择器(Selector)实现了多路复用,一个线程可以同时处理多个通道的IO操作,实现了更高的效率。NIO适用于连接数较多且连接时间较短的场景,例如网络编程中的ServerSocketChannel和SocketChannel。 AIO,即Asynchronous Input/Output,是Java在JDK1.7版本引入的一种新的IO模型。AIO通过回调机制实现异步的IO操作,当IO操作完成后会触发回调函数的执行。AIO适用于连接数较少且连接时间较长的场景,例如网络编程中的AsynchronousServerSocketChannel和AsynchronousSocketChannel。相比于NIO,AIO的优势是在IO操作完成前不需要阻塞线程,可以充分利用线程资源,并且编程模型更简单。 综上所述,IO是传统的同步IO模型,效率较低;NIO是一种非阻塞的IO模型,通过选择器实现了多路复用,效率较高;AIO是一种异步的IO模型,通过回调机制实现了非阻塞的IO操作,适用于连接时间较长的场景。在实际开发中,可以根据具体需求选择适合的IO模型来提高程序的性能和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值