首页 > 编程语言 >C# 接口IBufferWriter<T>学习理解

C# 接口IBufferWriter<T>学习理解

时间:2024-01-10 18:23:26浏览次数:32  
标签:C# 写入 接口 int length buffer IBufferWriter 缓冲区

IBufferWriter<T>是同步缓冲写入的协定,实现这个接口就拥有一个输出接收器

我是最近研究Protobuf序列化时发现它有个传递IBufferWriter<T>的构造,使用者只需要自己实现一个IBufferWriter<T>,创建后传递给Protobuf-net的序列化函数,就能得到其序列化后的字节流

先实现一个IBufferWriter<T>

    /// <summary>
    /// 实现IBufferWriter<T>接口的写入器
    /// </summary>
    public class BufferWriter : IBufferWriter<byte> {
        /// <summary>
        /// 缓冲区
        /// </summary>
        byte[] buffer;
        /// <summary>
        /// 缓冲区中数据的个数
        /// </summary>
        int length;
        /// <summary>
        /// 初始容量
        /// </summary>
        readonly int capacity;
        /// <summary>
        /// 创建一个缓冲区写入器
        /// </summary>
        /// <param name="capacity"></param>
        public BufferWriter(int capacity) {
            this.capacity = capacity;
            buffer = new byte[capacity];
        }
        /// <summary>
        /// 重置长度,复用该对象
        /// </summary>
        public void Reset() {
            length = 0;
        }
        /// <summary>
        /// 得到缓冲区中的数据
        /// </summary>
        /// <returns></returns>
        public (byte[], int) GetBuffer() {
            return (buffer, length);
        }
        /// <summary>
        /// 实现接口,
        /// </summary>
        /// <param name="count"></param>
        public void Advance(int count) {
            length += count;
        }
        /// <summary>
        /// 当缓冲区长度不足时,扩容缓冲区
        /// </summary>
        /// <param name="sizeHint"></param>
        void TryExpand(int sizeHint) {
            if (sizeHint + length > buffer.Length) {
                Array.Resize(ref buffer, buffer.Length + capacity);
            }
        }
        /// <summary>
        /// 返回缓冲区指定长度的可操作块
        /// </summary>
        /// <param name="sizeHint"></param>
        /// <returns></returns>
        public Memory<byte> GetMemory(int sizeHint = 0) {
            TryExpand(sizeHint);
            return buffer.AsMemory(length, sizeHint);
        }
        /// <summary>
        /// 返回缓冲区指定长度的可操作块
        /// </summary>
        /// <param name="sizeHint"></param>
        /// <returns></returns>
        public Span<byte> GetSpan(int sizeHint = 0) {
            TryExpand(sizeHint);
            return buffer.AsSpan(length, sizeHint);
        }
    }
View Code

写了一段测试代码来理解它

        public async Task Test() {
            await Task.CompletedTask;
            BufferWriter bw = new BufferWriter(1024); //这是一个缓冲区写入器
            for (int i = 0; i < 3; i++) { //循环测试其复用性
                bw.Reset(); //重置缓冲区复用创建的写入器对象
                TestWrite(bw);
                (byte[] buffer, int length) = bw.GetBuffer(); //得到缓冲区数据
                Console.WriteLine($"{string.Join(",", buffer.Take(length))}"); //输出写入的数据
            }
        }
        /// <summary>
        /// 模拟向缓冲区中写数据
        /// </summary> 
        void TestWrite(BufferWriter bw) {
            byte[] bytes = BitConverter.GetBytes(1024); //第一条数据,int32
            //使用接口中方法写入数据
            Span<byte> span = bw.GetSpan(bytes.Length); //先从申请一个span
            bytes.CopyTo(span); //然后将数据写入其中
            bw.Advance(bytes.Length);  //通知写入器已写入数据的长度

            //使用IBufferWriter<T>的扩展方法能直接写入数据 
            bw.Write(BitConverter.GetBytes(4096));  //第二条数据
        }
    }

 

标签:C#,写入,接口,int,length,buffer,IBufferWriter,缓冲区
From: https://www.cnblogs.com/luludongxu/p/17957066

相关文章

  • 使用React构造前端应用
    简单了解React和NodeReact是一个构建用户界面的JavaScript库,由Facebook开发,很流行,已被广泛使用。React基于组件构建,编写一段代码即可在多处复用,这很有优势。可以创建像Thumbnail、LikeButton和Video这样的组件,然后将它们组合成整个应用程序。React组件是JavaScript函数,学......
  • kubernetes-dashboard crashloopbackoff
    Kubernetes(简称K8S)是现阶段非常热门的容器编排平台,可以用于部署、扩展和管理容器化应用程序。Kubernetes提供了一个称为Dashboard的web界面,用于监视和管理集群中的各种资源。然而,有时我们可能会遇到kubernetes-dashboardcrashloopbackoff的问题,本篇文章将介绍这个问题的原因和解决......
  • rancher集群获取k8s的token
    你好,新入行的小伙伴!欢迎来到K8S的世界。今天,我将带你了解如何在Rancher集群中获取Kubernetes(K8s)的Token。这个过程可能会有些复杂,但别担心,我会尽可能地详细解释每一步。一、了解整体流程在开始之前,我们先大致了解一下整个流程。以下是获取KubernetesToken的基本步骤:登录到Rancher......
  • ios开发中:当一个 viewcontroller 中嵌套了一个 viewcontroller.view,pushViewcontrolle
    在iOS开发中,当你在一个UIViewController中嵌套另一个UIViewController的视图时,即使嵌套的视图能够正确显示,该嵌套的UIViewController实例可能不会被完全加入到视图控制器层次结构中。这可能导致一些问题,比如无法使用pushViewController:animated:方法进行导航。原因这种......
  • 软件测试/测试开发全日制|Pytest结合Excel实现数据驱动
    前言数据驱动测试是一种有效的测试方法,可以使用不同的输入数据运行相同的测试用例。结合pytest和Excel表格可以方便地实现数据驱动测试。在这篇文章中,我们将介绍如何使用pytest和Excel实现数据驱动测试。环境准备在实现Excel的数据驱动之前,我们首先要安装Python操作excel的第三方库......
  • php代码构建发送邮件的smtp接口操作流程
    构建发送邮件SMTP接口的PHP代码操作指南随着互联网的不断发展,电子邮件成为人们生活和工作中不可或缺的一部分。在Web开发中,通过PHP代码构建发送邮件的功能是常见的需求之一。本文将详细介绍如何使用PHP来构建和使用SMTP(SimpleMailTransferProtocol)接口,实现高效的邮件发送功能。......
  • [GXYCTF2019]Ping Ping Ping 1
    [GXYCTF2019]PingPingPing1审题由标题和内容,我们可以想到Linux的命令执行。并且由内容/?ip=,看出用GET注入ip变量来读取flag知识点Linux的命令执行,空格的绕过知识点详解在Linux中,竖线符号"|"和分号符号";"具有不同的作用。竖线符号"|"(管道符号):在Linux......
  • php代码构建发送邮件的smtp接口操作流程
    构建发送邮件SMTP接口的PHP代码操作指南随着互联网的不断发展,电子邮件成为人们生活和工作中不可或缺的一部分。在Web开发中,通过PHP代码构建发送邮件的功能是常见的需求之一。本文将详细介绍如何使用PHP来构建和使用SMTP(SimpleMailTransferProtocol)接口,实现高效的邮件发送功能。......
  • Helix QAC—软件静态测试工具
    产品概述    HelixQAC是Perforce公司(原PRQA公司)产品,主要用于C/C++代码的自动化静态分析工作,可以提供编码规则以及信息安全相关检查、代码质量度量、软件结构分析、测试结果管理等功能。HelixQAC能够准确地发现软件中潜在的问题,自身符合ISO26262功能安全标准认证。适用于......
  • MySQL Ignoring the redo log due to missing MLOG_CHECKPOINT between the checkpoin
    错误信息:2023-12-12T09:32:31.383149Z0[ERROR]InnoDB:IgnoringtheredologduetomissingMLOG_CHECKPOINTbetweenthecheckpoint5777611209andtheend5777612857.2023-12-12T09:32:31.384149Z0[ERROR]InnoDB:PlugininitializationabortedwitherrorGeneri......