C#实现ByteBuffer类 .

 在写网络程序的时候,经常需要往一个数组里面压数据或者取数据,而Java中再Java.nio中有个ByteBuffer能很方便的实现,Delphi中也有个Stream类有着同样的功能,这里我就模仿JAVA用C#做个最基础的ByteBuffer类

           下面是代码

          

using System;


namespace System.ByteBuffer
...{
    
/**//// <summary>
    
/// 创建一个可变长的Byte数组方便Push数据和Pop数据
    
/// 数组的最大长度为1024,超过会产生溢出
    
/// 数组的最大长度由常量MAX_LENGTH设定
    
/// 
    
/// 注:由于实际需要,可能要从左到右取数据,所以这里
    
/// 定义的Pop函数并不是先进后出的函数,而是从0开始.
    
/// 
    
/// @Author: Red_angelX
    
/// </summary>

    class ByteBuffer
    
...{
        
//数组的最大长度
        private const int MAX_LENGTH = 1024;
        
        
//固定长度的中间数组
        private byte[] TEMP_BYTE_ARRAY = new byte[MAX_LENGTH];
        
        
//当前数组长度
        private int CURRENT_LENGTH = 0;

        
//当前Pop指针位置
        private int CURRENT_POSITION = 0;

        
//最后返回数组
        private byte[] RETURN_ARRAY;

        
/**//// <summary>
        
/// 默认构造函数
        
/// </summary>

        public ByteBuffer()
        
...{
            
this.Initialize();
        }


        
/**//// <summary>
        
/// 重载的构造函数,用一个Byte数组来构造
        
/// </summary>
        
/// <param name="bytes">用于构造ByteBuffer的数组</param>

        public ByteBuffer(byte[] bytes)
        
...{
            
this.Initialize();
            
this.PushByteArray(bytes);
        }

    

        
/**//// <summary>
        
/// 获取当前ByteBuffer的长度
        
/// </summary>

        public int Length
        
...{
            
get
            
...{
                
return CURRENT_LENGTH;
            }

        }


        
/**//// <summary>
        
/// 获取/设置当前出栈指针位置
        
/// </summary>

        public int Position
        
...{
            
get
            
...{
                
return CURRENT_POSITION;
            }

            
set
            
...{
                CURRENT_POSITION 
= value;
            }

        }


        
/**//// <summary>
        
/// 获取ByteBuffer所生成的数组
        
/// 长度必须小于 [MAXSIZE]
        
/// </summary>
        
/// <returns>Byte[]</returns>

        public byte[] ToByteArray()
        
...{
            
//分配大小
            RETURN_ARRAY = new byte[CURRENT_LENGTH];
            
//调整指针
            Array.Copy(TEMP_BYTE_ARRAY, 0, RETURN_ARRAY, 0, CURRENT_LENGTH);
            
return RETURN_ARRAY;
        }


        
/**//// <summary>
        
/// 初始化ByteBuffer的每一个元素,并把当前指针指向头一位
        
/// </summary>

        public void Initialize()
        
...{
            TEMP_BYTE_ARRAY.Initialize();
            CURRENT_LENGTH 
= 0;
            CURRENT_POSITION 
= 0;
        }


        
/**//// <summary>
        
/// 向ByteBuffer压入一个字节
        
/// </summary>
        
/// <param name="by">一位字节</param>

        public void PushByte(byte by)
        
...{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= by;
        }


        
/**//// <summary>
        
/// 向ByteBuffer压入数组
        
/// </summary>
        
/// <param name="ByteArray">数组</param>

        public void PushByteArray(byte[] ByteArray)
        
...{
            
//把自己CopyTo目标数组
            ByteArray.CopyTo(TEMP_BYTE_ARRAY, CURRENT_LENGTH);
            
//调整长度
            CURRENT_LENGTH += ByteArray.Length;
        }


        
/**//// <summary>
        
/// 向ByteBuffer压入两字节的Short
        
/// </summary>
        
/// <param name="Num">2字节Short</param>

        public void PushUInt16(UInt16 Num)
        
...{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0xff00>> 8& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)((Num & 0x00ff& 0xff);
        }


        
/**//// <summary>
        
/// 向ByteBuffer压入一个无符Int值
        
/// </summary>
        
/// <param name="Num">4字节UInt32</param>

        public void PushInt(UInt32 Num)
        
...{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0xff000000>> 24& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x00ff0000>> 16& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x0000ff00>> 8& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)((Num & 0x000000ff& 0xff);
        }


        
/**//// <summary>
        
/// 向ByteBuffer压入一个Long值
        
/// </summary>
        
/// <param name="Num">4字节Long</param>

        public void PushLong(long Num)
        
...{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0xff000000>> 24& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x00ff0000>> 16& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x0000ff00>> 8& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)((Num & 0x000000ff& 0xff);
        }


        
/**//// <summary>
        
/// 从ByteBuffer的当前位置弹出一个Byte,并提升一位
        
/// </summary>
        
/// <returns>1字节Byte</returns>

        public byte PopByte()
        
...{
            
byte ret = TEMP_BYTE_ARRAY[CURRENT_POSITION++];
            
return ret;
        }


        
/**//// <summary>
        
/// 从ByteBuffer的当前位置弹出一个Short,并提升两位
        
/// </summary>
        
/// <returns>2字节Short</returns>

        public UInt16 PopUInt16()
        
...{
            
//溢出
            if (CURRENT_POSITION + 1 >= CURRENT_LENGTH)
            
...{
                
return 0;
            }

            UInt16 ret 
= (UInt16)(TEMP_BYTE_ARRAY[CURRENT_POSITION] << 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1]);
            CURRENT_POSITION 
+= 2;
            
return ret;
        }


        
/**//// <summary>
        
/// 从ByteBuffer的当前位置弹出一个uint,并提升4位
        
/// </summary>
        
/// <returns>4字节UInt</returns>

        public uint PopUInt()
        
...{            
            
if (CURRENT_POSITION + 3 >= CURRENT_LENGTH)
                
return 0;
            
uint ret = (uint)(TEMP_BYTE_ARRAY[CURRENT_POSITION] << 24 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1<< 16 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 2<< 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 3]);
            CURRENT_POSITION 
+= 4;
            
return ret;
        }


        
/**//// <summary>
        
/// 从ByteBuffer的当前位置弹出一个long,并提升4位
        
/// </summary>
        
/// <returns>4字节Long</returns>

        public long PopLong()
        
...{
            
if (CURRENT_POSITION + 3 >= CURRENT_LENGTH)
                
return 0;
            
long ret = (long)(TEMP_BYTE_ARRAY[CURRENT_POSITION] << 24 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1<< 16 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 2<< 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 3]);
            CURRENT_POSITION 
+= 4;
            
return ret;
        }


        
/**//// <summary>
        
/// 从ByteBuffer的当前位置弹出长度为Length的Byte数组,提升Length位
        
/// </summary>
        
/// <param name="Length">数组长度</param>
        
/// <returns>Length长度的byte数组</returns>

        public byte[] PopByteArray(int Length)
        
...{
            
//溢出
            if (CURRENT_POSITION + Length >= CURRENT_LENGTH)
            
...{
                
return new byte[0];
            }

            
byte[] ret = new byte[Length];
            Array.Copy(TEMP_BYTE_ARRAY, CURRENT_POSITION, ret, 
0, Length);
            
//提升位置
            CURRENT_POSITION += Length;
            
return ret;
        }


    }

}

           由于实际需要我是要从byteArray中从左到右取数据,所以才定义了一个CURRENT_POSITION的变量,如果需要从右到左弹数据并减小Buffer的长度则直接用 --CURRENT_LENGTH就可以了

转载于:https://www.cnblogs.com/anbylau2130/p/3233207.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/295144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql中如何删除表中int约束,MySQL中的约束,添加约束,删除约束,以及其他修饰

一.NOT NULL(非空约束)添加非空约束1)建表时直接添加CREATE TABLE t_user(user_id INT(10) NOT NULL);2)通过ALTER 语句ALTER TABLE t_user MODIFY user_id INT(10) NOT NULL;ALTER TABLE t_user CHANGE user_id user_id INT(10) NOT NULL;删除非空约束1)ALTER TABLE t_user MO…

asp.net 6中的mini api和mvc api性能对比

在.net6发布时&#xff0c;带来了一个新的模板框架&#xff0c;mini api&#xff0c;那与之前的mvc api性能对比是什么样的呢&#xff1f;建了基于.net 6的两种模板项目&#xff0c;都实现了一个get /test01的api请求&#xff0c;代码如下&#xff1a;mini api:app.MapGet(&quo…

lsass.exe文件丢失,损坏

有一天因为WSUS下发策略的时候更新了某些补丁&#xff0c;导致了系统在登录的时候提示lsass.exe文件丢失&#xff0c;损坏&#xff0c;一时间用了修复工具和恢复使用前都不行&#xff0c;于是好好研究了下。在一台完好使用的同一个系统的PC上复制了system32里面的lsass.exe&…

利用Guava的Suppliers.memoize实现单例

序 本文主要介绍如何利用Guava的Suppliers.memoize实现单例。 实例 /*** 利用Suppliers.memoize实现单例* Created by xixicat on 15/12/25.*/ public class SuppilerSingletonTest {class HeavyObject{public HeavyObject() {System.out.println("being created");}…

Android之水平ProgressBar多彩背景颜色

ProgressBar多彩的背景颜色 不废话,先爆照,如下图。 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_wi…

冰箱堪比「垃圾桶」?这根棒除味又保鲜,更能 99% 超强杀菌!

{}▲ 点击查看每天的饭菜、生鲜、零食、饮料、干货&#xff0c;总能把我家冰箱塞得满满当当。各种饭菜干货窜味儿&#xff0c;蔬果开始发烂发臭&#xff0c;每天打开冰箱都是一次「开门杀」……用柚子皮和竹炭包除味根本不行&#xff0c;从根源上改善冰箱环境才是硬道理。跟市面…

mac apache2 php,Mac OSX 之 PHP开发环境Apache2配置

time : 2018-03-23author : HGD_IS 李亮星一.事件因果一个星期前&#xff1a;不想下载XAMMP或者MAMP之类的IDE&#xff0c;而且下载完谷歌服务器一直只有放弃按钮&#xff0c;在Finder中打开也是不可打开文件状态&#xff0c;谷歌浏览器给出的解释是该App可能损害我的电脑&…

如何通过 C# 生成安全的 Base64 URL 字符串?

咨询区 Vishvesh Phadnis&#xff1a;在 C# 中如何实现对 URL 进行安全的 base64 编码&#xff0c;在 JAVA 中我可以使用 Codec 类库来实现此功能&#xff0c;我目前是这么实现的。byte[] toEncodeAsBytes System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode&quo…

System.getProperty()参数

java.version Java 运行时环境版本 java.vendor Java 运行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装目录 java.vm.specification.version Java 虚拟机规范版本 java.vm.specification.vendor Java 虚拟机规范供应商 java.vm.specificat…

不变模式

不变模式 不变模式&#xff08;immutable pattern&#xff09; 一个类的内部状态创建后&#xff0c;在整个生命期间都不会发生变化时&#xff0c;就是不变类。这种使用不变类的做法叫做不变模式。 不变模式有两种形式&#xff1a;一种是弱不变模式&#xff0c;另一种是强不变模…

了解SQL Server触发器及触发器中的事务

引述 首先&#xff0c;写这篇文章的目的是望能把我对触发器的理解&#xff0c;分享出来与大家一起学习。如果你对触发器和事务的概念有些了解&#xff0c;这篇文章对你来说会是很简单&#xff0c;或能让你更进一步的了解触发器里面的一些故事&#xff0c;以及触发器中事务的故…

swift学习笔记-----swift中的指针

swift语言为了简化&#xff0c;把指针隐形化了。没有像OC中那样的“ * ”。把底层的问题交给C语言去处理&#xff0c;我们可以在swift中调用C 语言来解决。当然&#xff0c;OC也是可以调用的。但是在某些场景下&#xff0c;这种调用可能不是很方便。比如&#xff0c;基于字节流…

多个php一个机器,如何利用docker在同一台机器上搭建多套php开发环境?

首先是一个容器要包含完整的程序加依赖(出去中间件)&#xff0c;拿 LNMP 举例子&#xff1a;docker 提供的是 Linux 环境&#xff0c;容器中要包含 Nginx 和 Php&#xff0c;然后再单独部署一个 MySQL其次&#xff0c;如果多个环境&#xff0c;可以使用多个容器&#xff0c;简单…

Android之Android studio如何解决Multiple dex files define Landroid/support/a(文件重复引用错误)

先爆错误的图片照,如下 define 可以理解文件重复的意思,所以这个错误是我导入了v4.jar包的原因,因为我项目里面本来就有v7.jar,如下图 解决办法一: 既然重复了,我就把这个v4.jar包删除掉,我删了之后就可以了,这个方法的前提是我知道哪个包重复了,不然我也不知道删除…

winform进度条实现

最近要给一个 Winform 项目添加功能&#xff0c;需要一个能显示进度条的弹窗&#xff0c;还要求能够中止任务&#xff0c;所以就做了一个&#xff0c;在此做个记录总结。虽然用的是比较老的 Winform 技术&#xff0c;不过其中的原理都是相通的。loading随处可见&#xff0c;比如…

keil之编辑环境配置

1.edit-->configuration 2. 3.开始是&#xff1a;ANSI编码&#xff0c;但一去掉&#xff1a;display modules&#xff0c;中文的注视就乱码了&#xff1b;请教Justchen&#xff0c;把编码改为GB2312&#xff0c;一切恢复正常&#xff1b;转载于:https://www.cnblogs.com/itl…

邮件服务器在企业网中的应用

简介&#xff1a; 电子邮件是因特网上最为流行的应用之一。如同邮递员分发投递传统邮件一样&#xff0c;电子邮件也是异步的&#xff0c;也就是说人们是在方便的时候发送和阅读邮件的&#xff0c;无须预先与别人协同。与传统邮件不同的是&#xff0c;电子邮件既迅速&#xff0c…

安卓事件机制与页面跳转

昨天学习了安卓开发中实现点击一个按钮实现页面的跳转。 首先点击一个按钮就会触发动作&#xff0c;这里就是给按钮加监听。一般对于事件监听&#xff0c;我们需要了解以下三类对象&#xff1a;事件源、事件、事件监听器&#xff0c;一般在安卓里&#xff0c;事件源就是指在哪个…

适配Win11!Edge重磅更新来袭

夜聊近日&#xff0c;微软对 Microsoft Edge 浏览器进行了两次重大更新。Microsoft Edge 95 正式版主要更新内容&#xff1a;版本号&#xff1a;95.0.1020.301.Microsoft Edge 右键菜单现已适配 Windows 11 风格&#xff0c;采用 Acrylic 和圆角设计&#xff0c;更加美观。2.你…

php 重定向到https,php – Laravel 5 – 重定向到HTTPS

您可以使它与中间件类工作。让我给你一个想法。namespace MyApp\Http\Middleware;use Closure;class HttpsProtocol {public function handle($request, Closure $next){if (!$request->secure() && env(APP_ENV) prod) {return redirect()->secure($request-&g…