IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> Java nio基本知识1:channel和buffer -> 正文阅读

[PHP知识库]Java nio基本知识1:channel和buffer

阻塞IO

读写时候阻塞,每个请求是一个线程

非阻塞IO

基于Reactor工作模式,IO不会阻塞,注册特定IO事件,发生特定事件时候系统会通知。核心对象是Selector,
读、写、注册发生时候selector可以找到发生事件的Selector Channel,获取客户端数据。

非阻塞IO事件本身不阻塞,但是获取事件的select()方法是阻塞的,本质是发生io时候,而不是以前只要IO流打开就一直等待。

NIO

核心组件:Channels Buffers Selectors

filechannel

写入文件小例子

public class io1 {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Users\\86158\\Desktop\\datax.txt");
        RandomAccessFile ra = new RandomAccessFile(f,"rw");
        FileChannel fc = ra.getChannel();

        //创建buffer
        ByteBuffer bf = ByteBuffer.allocate(1024);

        String input = "abcdefg";

        bf.clear();
        bf.put(input.getBytes());
        bf.flip();

        while (bf.hasRemaining()){
            fc.write(bf);
        }
        fc.close();
    }
}

FileChannel
position在某些特定位置进行读写
size返回文件大小
truncate 截取字节
force 强制写入
transferTo/transferFrom 通道间数据传输

通道间数据传输小例子

public class io2 {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Users\\86158\\Desktop\\datax.txt");
        File f2 = new File("C:\\Users\\86158\\Desktop\\datax2.txt");
        RandomAccessFile ra1 = new RandomAccessFile(f,"rw");
        RandomAccessFile ra2 = new RandomAccessFile(f2,"rw");
        FileChannel fc1 = ra1.getChannel();
        FileChannel fc2 = ra1.getChannel();

        //fc1数据传入fc2
        fc1.transferTo(0,fc1.size(),fc2);

    }
}


socketChannel

serverSocketChannel可以监听新进来的TCP连接的通道

监听8888端口

public class io3 {
    public static void main(String[] args) throws IOException, InterruptedException {
        int port = 8888;
        ByteBuffer bf = ByteBuffer.wrap("hello".getBytes());

        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(port));

        //设置非阻塞
        ssc.configureBlocking(false);

        //监听新链接传入
        while (true){
            SocketChannel sc = ssc.accept();
            if(sc == null){
                Thread.sleep(2000);
            }else {
                System.out.println(sc.socket().getRemoteSocketAddress());
                bf.rewind();
                sc.write(bf);
                sc.close();
            }

        }
    }
}

socketChannel
面向TCP

public class io4 {
    public static void main(String[] args) throws IOException {
        SocketChannel sc = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));

        sc.configureBlocking(false);
        ByteBuffer bf = ByteBuffer.allocate(100);
        sc.read(bf);
        sc.close();
        System.out.println("over");


    }
}

datagramChannel
面向UDP

public class io5 {

    public  void send() throws IOException, InterruptedException {
        DatagramChannel dc = DatagramChannel.open();
        InetSocketAddress ad = new InetSocketAddress("127.0.0.1",9999);
        while (true){
            ByteBuffer bf = ByteBuffer.wrap("jsjsjsj".getBytes());
            dc.send(bf,ad);
            System.out.println("发送");
            Thread.sleep(1000);
        }

    }

    public void receive() throws IOException {
        DatagramChannel dc = DatagramChannel.open();
        InetSocketAddress ad = new InetSocketAddress(9999);
        dc.bind(ad);
        ByteBuffer bf = ByteBuffer.allocate(1024);
        while (true){
            bf.clear();
            SocketAddress sc = dc.receive(bf);
            bf.flip();

            System.out.println(sc.toString() + bf);
        }



    }
}

channel的scatter和gather功能
在这里插入图片描述

在这里插入图片描述

Buffer

就是一块可以读写的内存空间,NIO中所有数据都用缓冲区处理

两种分配Buffer的方法:
ByteBuffer buf = ByteBuffer.allocate(10);
在堆中开辟,易于管理,垃圾回收器可以回收,空间有限,读写慢。

ByteBuffer buf2=ByteBuffer.allocateDirect(10);
物理内存中开辟空间,空间比较大,读写文件速度快,不受垃圾回收器控制。

buffer读写操作

public class io6 {
    public static void main(String[] args) throws IOException {
        buffer01();
    }

    public static void buffer01() throws IOException {
        RandomAccessFile ra = new RandomAccessFile("C:\\Users\\86158\\Desktop\\datax.txt","rw");
        FileChannel channel = ra.getChannel();
        ByteBuffer bf = ByteBuffer.allocate(1024);

        //读
        channel.read(bf);
        bf.flip();
        while (bf.hasRemaining()){
            System.out.println((char) bf.get());
        }
        bf.clear();


        //写
        for (int ii = 0; ii < bf.capacity();ii++){
            bf.put((byte) ii);
        }
        bf.flip();
        while (bf.hasRemaining()){
            System.out.println((char) bf.get());
        }
        bf.clear();

    }
}

buffer的属性 capacity position limit

capacity: 最多能写多少

position: 读写的当前位置,flip后变0

limit : 最多读到哪里(flip前的position)/最多写到哪里(capacity)

buffer放入数据两个方式

buffer.put()
channel.read(buffer)

buffer读数据
buffer.get()
channel.write(buffer)

rewind方法/flip方法

flip是写好了开始读,limit 要设成position,position变0

rewind是单纯position变0

clear方法/compact方法

clear: position设0
compact:准备好写数据了,未读过的数据不清除,未读数据拷贝到buffer起始处,position设为最后一个未读数据后面

mark方法/reset方法

mark标记特定position, reset恢复到这个position

buffer分片

在 NIO 中,除了可以分配或者包装一个缓冲区对象外,还可以根据现有的缓冲区对象
来创建一个子缓冲区,即在现有缓冲区上切出一片来作为一个新的缓冲区,但现有的
缓冲区与创建的子缓冲区在底层数组层面上是数据共享的,也就是说,子缓冲区相当
于是现有缓冲区的一个视图窗口。调用 slice()方法可以创建一个子缓冲区。

切片范围是调用slice方法时原始缓冲区的position到limit索引之间的数据

buffer只读

只读缓冲区非常简单,可以读取它们,但是不能向它们写入数据。可以通过调用缓冲
区的 asReadOnlyBuffer()方法,将任何常规缓冲区转 换为只读缓冲区,这个方法返
回一个与原缓冲区完全相同的缓冲区,并与原缓冲区共享数据,只不过它是只读的。
如果原缓冲区的内容发生了变化,只读缓冲区的内容也随之发生变化

区相当
于是现有缓冲区的一个视图窗口。调用 slice()方法可以创建一个子缓冲区。

切片范围是调用slice方法时原始缓冲区的position到limit索引之间的数据

buffer只读

只读缓冲区非常简单,可以读取它们,但是不能向它们写入数据。可以通过调用缓冲
区的 asReadOnlyBuffer()方法,将任何常规缓冲区转 换为只读缓冲区,这个方法返
回一个与原缓冲区完全相同的缓冲区,并与原缓冲区共享数据,只不过它是只读的。
如果原缓冲区的内容发生了变化,只读缓冲区的内容也随之发生变化

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:26:09  更:2021-09-22 14:27:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:29:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码