bytebuffer的容量极限和位置_bytebuffer写文件

bytebuffer的容量极限和位置_bytebuffer写文件缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区:使用缓冲区有这么两个好处:1、减少实际的物理读写次数2、缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数举个简单的例子,比如A地有1w块砖要搬到B地由于没有工具(缓冲区),我们一次只能搬一本,那么就要搬1w次(实际读写次数)如果A…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,这部分预留的内存空间就叫做缓冲区:

使用缓冲区有这么两个好处:

1、减少实际的物理读写次数

2、缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数

举个简单的例子,比如A地有1w块砖要搬到B地

由于没有工具(缓冲区),我们一次只能搬一本,那么就要搬1w次(实际读写次数)

如果A,B两地距离很远的话(IO性能消耗),那么性能消耗将会很大

但是要是此时我们有辆大卡车(缓冲区),一次可运5000本,那么2次就够了

相比之前,性能肯定是大大提高了。

而且一般在实际过程中,我们一般是先将文件读入内存,再从内存写出到别的地方

这样在输入输出过程中我们都可以用缓存来提升IO性能。

所以,buffer在IO中很重要。在旧I/O类库中(相对java.nio包)中的BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter在其实现中都运用了缓冲区。java.nio包公开了Buffer API,使得Java程序可以直接控制和运用缓冲区。

在Java NIO中,缓冲区的作用也是用来临时存储数据,可以理解为是I/O操作中数据的中转站。缓冲区直接为通道(Channel)服务,写入数据到通道或从通道读取数据,这样的操利用缓冲区数据来传递就可以达到对数据高效处理的目的。在NIO中主要有八种缓冲区类(其中MappedByteBuffer是专门用于内存映射的一种ByteBuffer):

bytebuffer的容量极限和位置_bytebuffer写文件

Fields

所有缓冲区都有4个属性:capacity、limit、position、mark,并遵循:mark <= position <= limit <= capacity,下表格是对着4个属性的解释:

属性 描述

Capacity

容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变

Limit

表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作。且极限是可以修改的

Position

位置,下一个要被读或写的元素的索引,每次读写缓冲区数据时都会改变改值,为下次读写作准备

Mark

标记,调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置

Methods

1、实例化

java.nio.Buffer类是一个抽象类,不能被实例化。Buffer类的直接子类,如ByteBuffer等也是抽象类,所以也不能被实例化。

但是ByteBuffer类提供了4个静态工厂方法来获得ByteBuffer的实例:

方法 描述

allocate(int capacity)

从堆空间中分配一个容量大小为capacity的byte数组作为缓冲区的byte数据存储器

allocateDirect(int capacity)

是不使用JVM堆栈而是通过操作系统来创建内存块用作缓冲区,它与当前操作系统能够更好的耦合,因此能进一步提高I/O操作速度。但是分配直接缓冲区的系统开销很大,因此只有在缓冲区较大并长期存在,或者需要经常重用时,才使用这种缓冲区

wrap(byte[] array)

这个缓冲区的数据会存放在byte数组中,bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方。其实ByteBuffer底层本来就有一个bytes数组负责来保存buffer缓冲区中的数据,通过allocate方法系统会帮你构造一个byte数组

wrap(byte[] array,

int offset, int length)

在上一个方法的基础上可以指定偏移量和长度,这个offset也就是包装后byteBuffer的position,而length呢就是limit-position的大小,从而我们可以得到limit的位置为length+position(offset)

我写了这几个方法的测试方法,大家可以运行起来更容易理解

public static void main(String args[]) throws FileNotFoundException {

System.out.println(“———-Test allocate——–“);

System.out.println(“before alocate:”

+ Runtime.getRuntime().freeMemory());

// 如果分配的内存过小,调用Runtime.getRuntime().freeMemory()大小不会变化?

// 要超过多少内存大小JVM才能感觉到?

ByteBuffer buffer = ByteBuffer.allocate(102400);

System.out.println(“buffer = ” + buffer);

System.out.println(“after alocate:”

+ Runtime.getRuntime().freeMemory());

// 这部分直接用的系统内存,所以对JVM的内存没有影响

ByteBuffer directBuffer = ByteBuffer.allocateDirect(102400);

System.out.println(“directBuffer = ” + directBuffer);

System.out.println(“after direct alocate:”

+ Runtime.getRuntime().freeMemory());

System.out.println(“———-Test wrap——–“);

byte[] bytes = new byte[32];

buffer = ByteBuffer.wrap(bytes);

System.out.println(buffer);

buffer = ByteBuffer.wrap(bytes, 10, 10);

System.out.println(buffer);

}

2、另外一些常用的方法

方法 描述

limit(), limit(10)等

其中读取和设置这4个属性的方法的命名和jQuery中的val(),val(10)类似,一个负责get,一个负责set

reset()

把position设置成mark的值,相当于之前做过一个标记,现在要退回到之前标记的地方

clear()

position = 0;limit = capacity;mark = -1;  有点初始化的味道,但是并不影响底层byte数组的内容

flip()

limit = position;position = 0;mark = -1;  翻转,也就是让flip之后的position到limit这块区域变成之前的0到position这块,翻转就是将一个处于存数据状态的缓冲区变为一个处于准备取数据的状态

rewind()

把position设为0,mark设为-1,不改变limit的值

remaining()

return limit – position;返回limit和position之间相对位置差

hasRemaining()

return position < limit返回是否还有未读内容

compact()

把从position到limit中的内容移到0到limit-position的区域内,position和limit的取值也分别变成limit-position、capacity。如果先将positon设置到limit,再compact,那么相当于clear()

get()

相对读,从position位置读取一个byte,并将position+1,为下次读写作准备

get(int index)

绝对读,读取byteBuffer底层的bytes中下标为index的byte,不改变position

get(byte[] dst, int offset, int length)

从position位置开始相对读,读length个byte,并写入dst下标从offset到offset+length的区域

put(byte b)

相对写,向position的位置写入一个byte,并将postion+1,为下次读写作准备

put(int index, byte b)

绝对写,向byteBuffer底层的bytes中下标为index的位置插入byte b,不改变position

put(ByteBuffer src)

用相对写,把src中可读的部分(也就是position到limit)写入此byteBuffer

put(byte[] src, int offset, int length)

从src数组中的offset到offset+length区域读取数据并使用相对写写入此byteBuffer

以下为一些测试方法:

public static void main(String args[]){

System.out.println(“——–Test reset———-“);

buffer.clear();

buffer.position(5);

buffer.mark();

buffer.position(10);

System.out.println(“before reset:” + buffer);

buffer.reset();

System.out.println(“after reset:” + buffer);

System.out.println(“——–Test rewind——–“);

buffer.clear();

buffer.position(10);

buffer.limit(15);

System.out.println(“before rewind:” + buffer);

buffer.rewind();

System.out.println(“before rewind:” + buffer);

System.out.println(“——–Test compact——–“);

buffer.clear();

buffer.put(“abcd”.getBytes());

System.out.println(“before compact:” + buffer);

System.out.println(new String(buffer.array()));

buffer.flip();

System.out.println(“after flip:” + buffer);

System.out.println((char) buffer.get());

System.out.println((char) buffer.get());

System.out.println((char) buffer.get());

System.out.println(“after three gets:” + buffer);

System.out.println(“\t” + new String(buffer.array()));

buffer.compact();

System.out.println(“after compact:” + buffer);

System.out.println(“\t” + new String(buffer.array()));

System.out.println(“——Test get————-“);

buffer = ByteBuffer.allocate(32);

buffer.put((byte) ‘a’).put((byte) ‘b’).put((byte) ‘c’).put((byte) ‘d’)

.put((byte) ‘e’).put((byte) ‘f’);

System.out.println(“before flip()” + buffer);

// 转换为读取模式

buffer.flip();

System.out.println(“before get():” + buffer);

System.out.println((char) buffer.get());

System.out.println(“after get():” + buffer);

// get(index)不影响position的值

System.out.println((char) buffer.get(2));

System.out.println(“after get(index):” + buffer);

byte[] dst = new byte[10];

buffer.get(dst, 0, 2);

System.out.println(“after get(dst, 0, 2):” + buffer);

System.out.println(“\t dst:” + new String(dst));

System.out.println(“buffer now is:” + buffer);

System.out.println(“\t” + new String(buffer.array()));

System.out.println(“——–Test put——-“);

ByteBuffer bb = ByteBuffer.allocate(32);

System.out.println(“before put(byte):” + bb);

System.out.println(“after put(byte):” + bb.put((byte) ‘z’));

System.out.println(“\t” + bb.put(2, (byte) ‘c’));

// put(2,(byte) ‘c’)不改变position的位置

System.out.println(“after put(2,(byte) ‘c’):” + bb);

System.out.println(“\t” + new String(bb.array()));

// 这里的buffer是 abcdef[pos=3 lim=6 cap=32]

bb.put(buffer);

System.out.println(“after put(buffer):” + bb);

System.out.println(“\t” + new String(bb.array()));

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186668.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 前端实现异步的几种方式_redux是什么

    前端实现异步的几种方式_redux是什么1.什么是Saga?实际上,这个术语出自康奈尔大学的一篇论文:http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf最初这篇论文是为了解决分布式系统中的LLT(LongLivedTransaction),也就是长时运行事务的数据一致性问题的。这么说有点抽象,我们来举个具体的例子:假如你在一个在线订票系统上订了一张…

  • 电信宽带_错误676_电话占线 解决办法

    电信宽带_错误676_电话占线 解决办法

    2021年11月17日
  • IDEA优化内存配置,可提高启动和运行速度(亲测有效)「建议收藏」

    IDEA优化内存配置,可提高启动和运行速度(亲测有效)「建议收藏」一、优化IDEA配置IDEA默认启动配置主要考虑低配置用户,参数不高(默认最低128m,最高512m),导致启动慢,然后运行也不流畅,这里我们需要优化下启动和运行配置;但是在工作中的电脑一般都是8G或者16G的运行内存,所以我们需要手动去修改默认的IDEA配置。二、手动修改IDEA配置步骤找到IDEA安装的bin目录打开idea.exe.vmoptions文件关键的三个参…

  • strstr函数实现

    strstr函数实现strstr()函数用来查找子串的首地址,函数实现如下:char*strstr(char*str1,char*str2){ char*p1=NULL; char*p2=NULL; while(*str1) { p1=str1; p2=str2; while(*p1==*p2&&*p2!=NULL) { p1++; p2…

  • 用Pycharm 直接下载Pyinstaller,以及使用问题解决

    用Pycharm 直接下载Pyinstaller,以及使用问题解决作为一个学语言学着玩的人,肯定很想把自己的学py文件打包发给别人,Pyinstaller包满足你。因为我一般下载包都是通过Pycharm下载的,有两个方法:一:在Pycharm中你输入:importPyinstaller#会报错只需要按住alt+回车下面就会出现是否安转此包,再回车一下等待就会自动安转完成;二:在Pycharm左上角的File->Setti…

  • 输油管的布置数学建模matlab,输油管布置的数学模型

    输油管的布置数学建模matlab,输油管布置的数学模型题研究—m⋯一一鼢|毳褥穰麓羧◎李银敏王作顺刘刚(广西贵港75130部队537100)【摘要】本论文研究了输油管线铺设最小费用问题,对问题1建立优化模型,运用函数极值理论及MATLAB软件求出最优解并给出了相应的铺设方案.首先我们运用机理分析说明公用管线必与铁路垂直,简化了问题,通过研究最一…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号