Netty:ByteBuf写入数据、读出数据

2023-11-14

介绍

  • Netty的ByteBuf数据位置索引是从0开始的,类似于数组。
  • getByte(int index):从指定位置读出一字节,这个操作不会改变ByteBuf的readerIndex或者 writerIndex 的位置。这个操作也不受readerIndex的影响(例如,当前readerIndex是1,但照样可以用getByte(0)从位置0处得到数据)。如果index小于0,或者index + 1大于ByteBuf的容量,就会抛出IndexOutOfBoundsException异常。
  • readByte():从当前readerIndex 读出一字节,并且将readerIndex的值增加1。如果ByteBuf的readableBytes的值小于1,就会抛出IndexOutOfBoundsException异常。
  • readBytes(byte[] dst):从当前readerIndex 读出dst.length个字节到字节数组dst中,并将buffer的readerIndex增加dst.length。操作完成后,buffer和数组dst的内容修改互不影响。
  • isReadable():方法判断是否有可读的数据。当(this.writerIndex -this.readerIndex) 的值大于0,isReadable()返回true。
  • writeShort(int value):在ByteBuf的当前writerIndex位置开始写入一个16位的整数,并且将writerIndex增加2。因为输入参数是int型,占4个字节,高位的16位被丢弃。
  • getShort(int index):从ByteBuf的绝对位置index开始,读取1个16位的整数。这个方法不改变ByteBuf的readerIndex和writerIndex。
  • getBytes(int index, byte[] dst):从ByteBuf的位置index开始,拷贝部分字节的内容到数组dst中,拷贝的字节数等于dst数组的长度。拷贝以后,再修改本buffer或者数组dst的内容互不影响。

代码举例

用getByte(int index)方法正常读取数据

代码:

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {		
		ByteBuf buf = Unpooled.buffer(1);		
		
		for (int i = 0; i < 1; i++) {
			buf.writeByte(0x68);
		}
		
		for (int i = 0; i < buf.capacity(); i++) {
			System.out.println(buf.getByte(i));
		}
	}

}

运行输出:
在这里插入图片描述

用getByte(int index)方法不正常读取数,据抛出异常

代码:

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {		
		ByteBuf buf = Unpooled.buffer(1);		
		
		for (int i = 0; i < 1; i++) {
			buf.writeByte(0x68);
		}
		
		for (int i = 0; i < buf.capacity() + 1; i++) {
			System.out.println(buf.getByte(i));
		}
	}

}

运行输出:
在这里插入图片描述

用getByte(int index)获取数据不受buffer的readerIndex的影响

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Demo {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer();
		buf.writeByte(104);
		buf.writeByte(22);
		buf.readByte();
		System.out.println("buf.readerIndex: " + buf.readerIndex());
		// 尽管当前readerIndex是1,但照样可以从位置0处获得数据
		System.out.println("buf.getByte(0): " + buf.getByte(0));
	}

}

运行输出:

buf.readerIndex: 1
buf.getByte(0): 104

用readByte()方法正常读取数据–用readableBytes()判断可读的数据字节数

代码:

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {		
		ByteBuf buf = Unpooled.buffer(2);		
		
		for (int i = 0; i < 2; i++) {
			buf.writeByte(0x68);
		}		
		
		while (buf.readableBytes() > 0) {
			System.out.println(buf.readByte());
		}
	}

}

运行输出:
在这里插入图片描述

用readBytes(int length)方法读取一定数量的字节到一个新创建的ByteBuf中

readBytes(int length)方法是从当前的ByteBuf的readerIndex开始,读取length字节的数据到一个新创建的ByteBuf中,并将readerIndex增加length。

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer();
		// 往buf中写入10个字节的数据
		for (int i =0; i < 10; i++) {
			buf.writeByte(0x68);
		}
		
		// 从buf中读取所有可读的数据到新创建的ByteBuf中
		ByteBuf dst = buf.readBytes(buf.readableBytes());
		System.out.println("dst.readableBytes(): " + dst.readableBytes());
		System.out.println("dst.capacity(): " + dst.capacity());
	}
}

运行输出:

dst.readableBytes(): 10
dst.capacity(): 10

用readBytes(byte[] dst) 读出部分数据到字节数组中,操作完成后,buffer和数组的内容修改互不影响

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Demo {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer();
		buf.writeByte(104);
		buf.writeByte(22);
		byte[] dst = new byte[2];
		buf.readBytes(dst);
		System.out.println("before byte array change, dst[0] = " + dst[0]);
		System.out.println("before byte array change, buf.getByte(0): " + buf.getByte(0));
		dst[0] = (byte)33;
		dst[1] = (byte)33;
		System.out.println("after byte array change, dst[0] = " + dst[0]);
		System.out.println("after byte array change, buf.getByte(0): " + buf.getByte(0));
	}

}

运行输出:

before byte array change, dst[0] = 104
before byte array change, buf.getByte(0): 104
after byte array change, dst[0] = 33
after byte array change, buf.getByte(0): 104

用readByte()方法正常读取数据–用isReadable()判断是否有可读的数据

isReadable():当ByteBuf的(writerIndex - readerIndex) > 0返回true。

代码:

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {		
		ByteBuf buf = Unpooled.buffer(2);		
		
		for (int i = 0; i < 2; i++) {
			buf.writeByte(0x68);
		}		
		
		while (buf.isReadable()) {
			System.out.println(buf.readByte());
		}
	}

}

运行输出:
在这里插入图片描述

用isReadable(int size)判断是否有size个字节可读

isReadable(int size):如果ByteBuf中有size个字节可读,结果返回true。

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer();
		// 往buf中写入5个字节的数据
		for (int i =0; i < 5; i++) {
			buf.writeByte(0x68);
		}
		
		// 判断buf是否有5个字节可读,结果为true
		System.out.println(buf.isReadable(5));
		// 读出1个字节,readerIndex加1,还剩4个可读字节
		buf.readByte();
		// 再次判断buf是否有5个字节可读,结果为false
		System.out.println(buf.isReadable(5));
	}
}

运行输出:

true
false

用getBytes(int index, byte[] dst)读取部分内容到数组中

getBytes(int index, byte[] dst)表示从ByteBuf的绝对位置index开始,拷贝部分内容到目的字节数组中。这个操作不改变ByteBuf的readerIndex 和 writerIndex。

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {		
		ByteBuf buf = Unpooled.buffer(4);
		for (int i = 0; i < buf.capacity(); i++) {
			buf.writeByte(0x68);
		}
		
		byte[] data = new byte[2];
		// 从buf的第二个字节开始,拷贝2个字节的内容到data数组中
		buf.getBytes(1, data);
		System.out.println("数组data的内容:");
		for (int i = 0; i < data.length; i++) {
			System.out.println(data[i]);
		}
		
		System.out.println("buf的内容:");
		for (int i = 0; i < buf.capacity(); i++) {
			System.out.println(buf.getByte(i));
		}
	}

}

运行结果:
在这里插入图片描述

用getBytes(int index, byte[] dst)读取部分内容到数组中,拷贝完后后,修改本buffer或者数组的内容互不影响

拷贝完后后,修改本buffer或者数组的内容互不影响。

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Demo {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer(4);
		for (int i = 0; i < buf.capacity(); i++) {
			buf.writeByte(i + 10);
		}
		
		byte[] data = new byte[2];
		// 从buf的第1个字节开始,拷贝2个字节的内容到data数组中
		buf.getBytes(0, data);
		System.out.println("content of data[0]:" + data[0]);
		System.out.println("content of data[1]:" + data[1]);
		System.out.println("-----------------------------");
		
		// 修改buffer第1个字节的内容
		buf.setByte(0, 0x16);
		System.out.println("buf.getByte(0):" + buf.getByte(0));
		// 修改buffer的内容不会改变数组的内容
		System.out.println("content of data[0]:" + data[0]);
		System.out.println("content of data[1]:" + data[1]);
	}

}

运行输出:

content of data[0]:10
content of data[1]:11
-----------------------------
buf.getByte(0):22
content of data[0]:10
content of data[1]:11

用writeShort(int value)写入一个short型整数,用getShort(int index)读取一个short型整数

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {		
		ByteBuf buf = Unpooled.buffer(4);
		buf.writeShort(2048);
		// 从buf中读取一个short型整数并打印出来,看是否和传入的相同
		System.out.println("从ByteBuf中读取的short型整数为:" + buf.getShort(0));
	}

}

运行结果:
在这里插入图片描述

写入数据少,读出数据多,但只要没有超过ByteBuf的容量,就不会抛异常

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer(10);
		buf.writeByte(0x68);  // 写入1个字节
		System.out.println("current capacity: " + buf.capacity());   // 当前容量是10个字节
		
		System.out.println(buf.getByte(0)); 	// 读1个字节0x68,结果正确
		System.out.println(buf.getShort(0));   // 读2个字节0x6800,结果不正确了
		System.out.println(buf.getLong(0));   // 读8个字节0x6800000000000000,结果不正确了
	}
}

输出:

current capacity: 10
104
26624
7493989779944505344

从上面的输出结果可以看出,写入少,读出多,只要没有超过ByteBuf的容量,尽管不会抛异常,但结果已经不正确了。

换一种读出方法,用低端字节序读出:

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer(10);
		buf.writeByte(0x68);
		System.out.println("current capacity: " + buf.capacity());
		
		System.out.println(buf.getByte(0)); 	// 读1个字节0x68	
		System.out.println(buf.getShortLE(0));   // 读2个字节0x0068
		System.out.println(buf.getLongLE(0));   // 读8个字节0x0000000000000068
	}
}

输出结果:

current capacity: 10
104
104
104

用writeBytes(ByteBuf src)函数将源ByteBuf 的数据写入本ByteBuf 中

writeBytes(ByteBuf src)函数的参数是源ByteBuf。
该函数将源ByteBuf中的内容写到本ByteBuf 中。数据传递完成后,源ByteBuf的readerIndex增长传递的字节数,本ByteBuf的writerIndex增长传递的字节数。
如果本ByteBuf的容量不够,会试图扩大容量。

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class Test {

	public static void main(String[] args) {
		// 创建一个ByteBuf
		ByteBuf srcBuf = Unpooled.buffer();
		// 写入10个字节
		for (int i = 0; i < 10; i++) {
			srcBuf.writeByte(0x68);  
		}
		
		// 创建一个ByteBuf
		ByteBuf dstBuf = Unpooled.buffer();
		dstBuf.writeBytes(srcBuf);
		System.out.println("srcBuf.readerIndex: " + srcBuf.readerIndex());
		System.out.println("srcBuf.writerIndex: " + srcBuf.writerIndex());
		System.out.println("dstBuf.readerIndex: " + dstBuf.readerIndex());
		System.out.println("dstBuf.writerIndex: " + dstBuf.writerIndex());
	}
}

运行输出:

srcBuf.readerIndex: 10
srcBuf.writerIndex: 10
dstBuf.readerIndex: 0
dstBuf.writerIndex: 10

getByte(int index)和getUnsignedByte(int index)的对比

package com.thb;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ByteProcessor;

public class Test {

	public static void main(String[] args) {
		// 创建一个ByteBuf
		ByteBuf buf = Unpooled.buffer();
		
		byte b = (byte)0xfe;
		// 写入数据
		buf.writeByte(b);
		
		// 用两种方法分别读出数据
		System.out.println("buf.getByte: " + buf.getByte(buf.readerIndex()));
		System.out.println("buf.getUnsignedByte: " + buf.getUnsignedByte(buf.readerIndex()));
	}
}

运行输出:

buf.getByte: -2
buf.getUnsignedByte: 254
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Netty:ByteBuf写入数据、读出数据 的相关文章

  • java程序有多少种结束方式?

    我知道使用 System exit 0 可以结束一个java程序 例如 如果我有一个JFrame窗口 它会关闭并结束程序 但我想知道还有多少其他方法 可以关闭它并结束程序 包括发生错误时 程序会被关闭 JFrame也会被关闭吗 添加到其他答
  • Java 中的 <-- 是什么? [复制]

    这个问题在这里已经有答案了 我遇到了下面的片段 它输出到4 3 2 1 我从来没有遇到过 lt 在爪哇 Is lt 使 var1 的值变为 var2 的运算符 public class Test public static void mai
  • 无法使用 datastax java 驱动程序通过 UDT 密钥从 cassandra 检索

    我正在尝试使用用户定义的类型作为分区键将对象存储在 cassandra 中 我正在使用 datastax java 驱动程序进行对象映射 虽然我能够插入到数据库中 但无法检索该对象 如果我更改分区键以使用非 udt 例如文本 我就能够保存和
  • JOOQ 忽略具有默认值的数据库列

    看来JOOQ完全忽略了数据库列的默认值 既不会更新 ActiveRecord 对象 也不会在 INSERT 时跳过此列 相反 它尝试将其设置为 NULL 这在 NOT NULL 列上失败 Example CREATE TABLE bug f
  • 将类转换为 JSONObject

    我有好几堂这样的课 我想将类转换为 JSONObject 格式 import java io Serializable import com google gson annotations SerializedName public cla
  • 为什么 jar 执行的通配符在 docker CMD 中不起作用?

    我有一个Dockerfile与以下CMD启动我的 Spring Boot 应用程序 FROM java 8 jre CMD java jar app file jar 当我尝试从创建的图像启动容器时 我得到 Error Unable to
  • Java AES 256 加密

    我有下面的 java 代码来加密使用 64 个字符密钥的字符串 我的问题是这会是 AES 256 加密吗 String keyString C0BAE23DF8B51807B3E17D21925FADF273A70181E1D81B8EDE
  • 为什么在将 String 与 null 进行比较时会出现 NullPointerException?

    我的代码在以下行中出现空指针异常 if stringVariable equals null 在此语句之前 我声明了 stringVariable 并将其设置为数据库字段 在这个声明中 我试图检测该字段是否有null值 但不幸的是它坏了 有
  • IntelliJ Idea:将简单的 Java servlet(无 JSP)部署到 Tomcat 7

    我尝试按照教程进行操作here http wiki jetbrains net intellij Creating a simple Web application and deploying it to Tomcat部署 servlet
  • UseCompressedOops JVM 标志有什么作用以及何时应该使用它?

    HotSpot JVM 标志是什么 XX UseCompressedOops我应该做什么以及什么时候使用它 在 64 位 Java 实例上使用它 与不使用它 时 我会看到什么样的性能和内存使用差异 去年大多数 HotSpot JVM 都默认
  • 数据库中的持久日期不等于检索日期

    我有一个具有 Date 属性的简单实体类 此属性对应于 MySQL 日期时间列 Entity public class Entity Column name start date Temporal TemporalType TIMESTAM
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • 文本视图不显示全文

    我正在使用 TableLayout 和 TableRow 创建一个简单的布局 其中包含两个 TextView 这是代码的一部分
  • Lombok 不适用于 Eclipse Neon

    我下载了lombok jar lombok 1 16 14 jar 并将其放入我的下载中 然后我点击这个 jar 执行正确地识别了我的 MacOS 上的 Eclipse 实例 然后我选择了我想要的实例 Lombok也在pom xml中指定
  • titledBorder 标题中的图标

    您好 是否可以在 titledBorder 的标题中放置一个图标 例如以下代码 import java awt GridLayout import javax swing JFrame import javax swing JLabel i
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • Selenium 单击在 Internet Explorer 11 上不起作用

    我尝试在 Internet Explorer 上单击 selenium 但它不起作用 我努力了element click moveToElement element click build perform javascript没事了 事实上
  • 在会话即将到期之前调用方法

    我的网络应用程序有登录的用户 有一个超时 在会话过期之前 我想执行一个方法来清理一些锁 我已经实现了sessionListener但一旦我到达public void sessionDestroyed HttpSessionEvent eve
  • 设置 TreeSet 的大小

    有没有办法像数组一样对 Java 集合中的 TreeSet 进行大小限制 例如我们在数组中 anArray new int 10 数组具有固定长度 在创建数组时必须指定该长度 A TreeSet当您向其中添加元素时会自动增长 您无法设置其大

随机推荐

  • Exception in thread “main“ java.lang.ArrayIndexOutOfBoundsException: 6问题

    今天在java中出现了一个这样的问题 Exception in thread main java lang ArrayIndexOutOfBoundsException 6 at com wyt demo3 Role attack Role
  • valgrind android编译、安装

    valgrind android编译 安装 参见valgrind 3 12 0 tar bz2中的README android文件 以下步骤 遵循README android说明 注意VALGRIND LIB是程序内部环境变量 export
  • static在C和C++中的区别

    以下内容参考博客 https www cnblogs com Manual Linux p 8870038 html static在C语言中的区别 1 static修饰变量的时候 静态局部变量只被执行一次 延长了整个局部变量的生命周期 直到
  • linux下RDP客户端及服务器

    tsclient redsktop remmina gt 对ubuntu支持的非常不错 XRdp 集合vnc作为rdp服务器端使用
  • Java注释及分隔符 基础知识

    一 用于单行注释 用于多行注释 文档注释 文档注释属于多行注释的一种 二 空白符 空格 制表符 t 走页换页 f 回车 r 换行 n
  • 使用python指定个数随机生成一组混合字符集

    今天做测试想生成混合的id或者密码 思考了有很多方式 比如可以加入datetime库 然后截取一部分 或者随机生成一部分 进行替换 添加 这里采取一种简单易懂的方式 一 运行结果示范 就是这种效果 生成多少位数 18 ry3Gu aVr8V
  • STM32 基础系列教程 30 - 文件系统

    前言 学习stm32中FATFS 文件系统的基础使用 学会文件的打开及读写删除等基本操作 理解文件系统基本概念 示例详解 基于硬件平台 STM32F10C8T6最小系统板 MCU 的型号是 STM32F103c8t6 使用stm32cube
  • 学习HC-SR04超声波测距模块,代码附带卡尔曼滤波

    硬件引脚 VCC 供5V的电压 一定要是5v GND 接地 Trig HC SR04超声波测距模块上的触发引脚 用于向模块发送一个10微秒的高电平触发信号 触发模块开始进行距离测量 Echo 用于接收超声波回波信号的引脚 工作原理 使用HC
  • js根据本地文件路径上传文件(流上传)

    最近使用vue做了个项目 把本地指定url下的png图片上传 废话不多说 直接上代码 var fs require fs 需要引入nodejs中的文件操作部分 var http require http 需要引入nodejs中http请求部
  • 软件自动化测试工具/平台的挑战

    今天在微信读书偶然读到 高效自动化测试平台 设计与开发实战 作者徐德晨和茹炳晟 该书1 2章节详细讲述了软件自动化测试工具 平台的七个挑战 下面结合一站式开源持续测试平台项目MeterSphere详解这七个挑战 GitHub metersp
  • linux系统编程-1、基础知识

    前言 Linux系统编程的基础系列文章 随着不断学习会将一些知识点进行更新 前期主要是简单了解和学习 文章目录 shell bash 命令和路经补齐 历史记录 目录和文件 类Unix系统目录结构 用户目录 ls cd which pwd m
  • 请用美丽欢呼-------Day38

    周末 双休 疯了两天 敲了寥寥的代码 却没少看了相关的文章 这电子书大行于世的年代 对工具的漠然简直就是对生命的亵渎 颠簸的公交车上算是告别了YY的惬意 这生活 感觉傻了点 可真够味 原本只是想写篇 html的发展历程 的 可XHTML 2
  • Java并发编程:并发容器之CopyOnWriteArrayList(转载)

    http www cnblogs com dolphin0520 p 3938914 html 原文链接 http ifeve com java copy on write Copy On Write简称COW 是一种用于程序设计中的优化策
  • 基于YOLOv8模型和CrowdHuman数据集的行人检测系统(PyTorch+Pyside6+YOLOv8模型)

    摘要 基于YOLOv8模型和CrowdHuman数据集的行人目标检测系统可用于日常生活中检测与定位行人 Human 利用深度学习算法可实现图片 视频 摄像头等方式的目标检测 另外本系统还支持图片 视频等格式的结果可视化与结果导出 本系统采用
  • python 利用表格批量修改文件夹(包括子文件夹)下所有文件名

    首先是获得需要修改文件的路径放入xlsx中 我一般直接在系统的搜索框中搜索 然后全选复制路径 偷个小懒 也可以再写个自动遍历所有文件获取地址 点击这个复制路径即可复制全部选中文件的路径 直接复制在表格第一列即可 便于读取 然后按照自己实际的
  • SQL调优的几个方法

    1 为什么调优 好处是什么 SQL语句在编写之后 对于数据量较少的表基本没有什么性能上的需求 但是如果考虑到性能方面的话 SQL语句优化就是必须的 2 如何调优 调有点方法有哪些 1 对查询进行优化 应尽量避免全表扫描 首先考虑在where
  • node 版本管理器 --- Volta

    鲸腾FE 来自恒生鲸腾网络 是一支专注于 web 前端的开发团队 并在 web 前端领域积累了多年疑难问题解决经验 崇尚高效 优质 成长 自由 快乐 前言 在我们的日常开发中经常会遇到这种情况 手上有好几个项目 每个项目的需求不同 然而不同
  • uniapp 原生安卓开发插件(module),以及android环境本地调试(一)

    uniapp 原生安卓开发插件 module 以及android环境本地调试 1 开发前景 由于uniapp 框架的局限先 有很多功能不能如原生android开发使用顺畅 因此 需要使用插件进行辅助 再由uniapp引入插件 使得功能完善
  • Linux设备驱动开发详解总结(二)之并发与竞争

    转载地址 http blog csdn net lwj103862095 article details 8548500 Linux设备驱动中必须解决一个问题是多个进程对共享资源的并发访问 并发的访问会导致竞态 在当今的Linux内核中 支
  • Netty:ByteBuf写入数据、读出数据

    介绍 Netty的ByteBuf数据位置索引是从0开始的 类似于数组 getByte int index 从指定位置读出一字节 这个操作不会改变ByteBuf的readerIndex或者 writerIndex 的位置 这个操作也不受rea