这个把source缓冲区中的数据写到当前缓冲区的方法是比较经典的:

   if (source == null) throw new IllegalArgumentException("source == null");
//这个判断是防止自己把数据写到自身这个Buffer中
if (source == this) throw new IllegalArgumentException("source == this");
//每个Segment中最大存储的自己是8k,因此写的时候需要进行校验
checkOffsetAndCount(source.size, 0, byteCount); //核心设计来了
每次读取source中的数据时,都是从head开始,如果当前的剩余的byteCount小于head中的有效数据
判断当前buffer中的尾Segment有没有操作权限并且可用空间能否放得下当前剩余的byteCount,如果可以放的下直接
调用source.head.writeTo(tail, (int) byteCount)方法把source中的数据写进tail中;结束
否则就把head分割成两部分。 此时source的head就是分割的后一个Segment,而前一个Segment则给到了当前的Segment了,成为了他的尾Segment。 while (byteCount > 0) {
// 说明当前剩余的长度包含在了source的头中,也意味着循环的结束
if (byteCount < (source.head.limit - source.head.pos)) {
//找到当前Segment的尾部
Segment tail = head != null ? head.prev : null;
//权限判断和可用空间的判断是否都符合写入条件
if (tail != null && tail.owner
&& (byteCount + tail.limit - (tail.shared ? 0 : tail.pos) <= Segment.SIZE)) {
//如果符合要求,那就直接把source中byteCount长度的字节移动到tail中
source.head.writeTo(tail, (int) byteCount);
//更新source的长度
source.size -= byteCount;
//更新当前缓冲区的长度
size += byteCount;
//结束
return;
} else { //不符合上述条件的,我没就通过split把head分割成2部分,前一部分就是我们需要写入的数据,此时也是source的头Segment
source.head = source.head.split((int) byteCount);
}
} //需要移动的就是source的头
Segment segmentToMove = source.head;
//计算移动的长度,更新会用到
long movedByteCount = segmentToMove.limit - segmentToMove.pos;
//通过pop方法位source指定新的head
source.head = segmentToMove.pop();
//如果当前的buffer时空的,那么segmentToMove直接作为buffer的头即可
if (head == null) {
head = segmentToMove;
head.next = head.prev = head;
} else {
//否则就把segmentToMove插入到尾部
Segment tail = head.prev;
tail = tail.push(segmentToMove);
//这里还进行了一次压缩:里面也会进行write操作
tail.compact();
}
//更新source的长度
source.size -= movedByteCount;
//更新当前缓冲区的长度
size += movedByteCount;
//更新剩余需要写入的长度
byteCount -= movedByteCount;
}

Buffer中的public void write(Buffer source, long byteCount)解析的更多相关文章

  1. Android开发之Source无法覆写public void onClick(View v)

    初学Android开发,在为一个按钮[该按钮继承OnClickListener()]写监听时,发现无法在Source中引入public void onClick(View v),当时非常纳闷,平常情况 ...

  2. 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式

    Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...

  3. Java NIO Buffer中各种状态属性的含义

    关于NIO Buffer中的3个重要状态属性的含义: postion, limit与capacity. public class NioTest { public static void main(S ...

  4. java.nio.Buffer 中的 flip()方法

    在Java NIO编程中,对缓冲区操作常常需要使用  java.nio.Buffer中的 flip()方法. Buffer 中的 flip() 方法涉及到 Buffer 中的capacity.posi ...

  5. 从depth buffer中构建view-space position

    观察透视投影矩阵: 对于x和y,矩阵变换只是一个缩放系数,那么逆变换就是缩放系数的倒数,所以 设Xndc Yndc为NDC空间中的XY坐标,Xview Yview Zview为view space中的 ...

  6. 在java中public void与public static void有什么区别 ?

    public void 修饰是非静态方法,该类方法属于对象,在对象初始化(new Object())后才能被调用:public static void 修饰是静态方法,属于类,使用类名.方法名直接调用 ...

  7. linux中内存使用,swap,cache,buffer的含义总结

    首先介绍一下linux中内存是如何使用的.当有应用需要读写磁盘数据时,由系统把相关数据从磁盘读取到内存,如果物理内存不够,则把内存中的部分数据导入到磁盘,从而把磁盘的部分空间当作虚拟内存来使用,也称为 ...

  8. 在java中public void与public static void区别

    static 方法可以被main方法直接调用,而非static方法不可以.因为static方法是属于类的,是类方法.可以通过类名.方法名直接调用.而非static方法必须等对象被new出来以后才能使用 ...

  9. Linux系统中的Page cache和Buffer cache

    Linux系统中的Page cache和Buffer cache Linux中有两个很容易混淆的概念,pagecache和buffercache,首先简单将一些Linux系统下内存的分布,使用free ...

  10. (1)定义一个接口CanFly,描述会飞的方法public void fly(); (2)分别定义类飞机和鸟,实现CanFly接口。 (3)定义一个测试类,测试飞机和鸟,在main方法中创建飞机对象和鸟对象, 再定义一个makeFly()方法,其中让会飞的事物飞。并在main方法中调用该方法, 让飞机和鸟起飞。

    package b; public interface CanFly { public void fly(); } package b; public class FeiJi implements C ...

随机推荐

  1. Pintia 7-3 列车调度

    7-3 列车调度 (25 分) 火车站的列车调度铁轨的结构如下图所示. 两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道.每趟列车从入口可以选择任意一条轨 ...

  2. 使用git&GitHub通过两台电脑协同作业,助力办公室摸鱼

    前情提要:工作有时候负荷比较小,会接一些咸鱼上的活儿或者自己学点软件技能,这时候会出现一个情况,公司笔记本一般不带回家,家里台式机,白天在公司摸鱼编辑的文件,晚上回家想接着干怎么办呢,或是晚上在家干的 ...

  3. 代理模式_v1

    代理模式 概念: 1.真实对象:要被代理的对象 2.代理对象 3.代理模式 : 代理对象代理真实对象,达到增强真实对象功能的作用 实现方式: 1.静态代理:有一个类文件描述代理模式 2.动态代理:在内 ...

  4. PriorityQueue&&Function overload

    用 STL 里面堆算法实现的与真正的STL里面的 priority_queue用法相似的priority_queue    #include <iostream>    #include ...

  5. PASS模型小程序设计阶段-里程碑第三组

    班级网址 https://edu.cnblogs.com/campus/zjcsxy/SE2020 作业要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/ ...

  6. 输入一段字符(只含有空格和字母,保证开头不为空格),里面有若干个字符串,求这些字符串的长度和,并输出最长字符串内容,如果有多个输出最先出现的那个字符串。以stop作为最后输入的字符串。

    #include<stdio.h>#include<string.h>main(){    int i,j=0,m,count,max;    char a[100];     ...

  7. 第3章---数据探索(python数据挖掘)

    1.缺失值分析及箱型图 数据:catering_sale.xls(餐饮日销额数) 缺失值使用函数:describe()函数,能算出数据集的八个统计量 import pandas as pd cater ...

  8. Json对象转换模块(自编代码JsonObject.cs)

    namespace 信息采集系统.Common { /// <summary> /// Json类型对象,用于其它Json对象继承 /// </summary> /// < ...

  9. 使用 netstat 命令监视网络状态

    在linux 系统网络出现问题时可以使用netstat -s 来分析问题 使用 netstat 命令监视网络状态 netstat 命令生成包含网络状态和协议统计信息的显示内容.可以通过表格形式显示 T ...

  10. 2021SWPUCTF-WEB(二)

    ez_unserialize ​ 不知道在哪,御剑扫叭 ​ 有一个robots.txt ​ ​ 一道反序列化好像是 分析代码应该是admin=admin.passwd=ctf即可输出flag < ...