• 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就可以了

  • 相关阅读:
    Preserving Remote IP/Host while proxying
    使用EF Core生成实体类 用来作为NetCore数据库访问上下文 Context
    【ASP.NET Core快速入门】(八)Middleware管道介绍、自己动手构建RequestDelegate管道
    NetCore WebApi 基于Jwt的验证授权方式
    Net Core 页面的生命周期 + OnActionExecuting
    C# 多线程发送邮件 代码版
    ASP.NET Core 中的过滤器(Action过滤器,控制器过滤器,全局应用程序过滤器)
    深入理解 NetCore 中的依赖注入的好处 及 、Singleton、Scoped、Transient 三种对象的差异
    巧用 display: contents 增强页面语义
    巧妙实现带圆角的渐变边框
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/3233207.html
Copyright © 2020-2023  润新知