C# 自定义配置文件序列化生成+文件格式错误自动回档

news2024/11/6 7:24:34

文章目录

  • 前言
  • 选择Xml
  • 简单的Xml使用
    • 测试用例
    • 简单的写
    • 简单的读
    • 简单的生成配置
      • 修改配置类
      • 测试用例
      • 运行结果对比
  • 代码逻辑封装
    • 逻辑示意
    • 封装好的代码
    • 测试生成
    • 配置文件格式错误测试
      • 使用默认值覆盖来解决问题
  • 配置文件人为修改错误如何解决
    • 解决方案
    • 代码
    • 测试用例
    • 运行结果
  • 代码封装总结
  • 总结

前言

一般我们代码生成了之后,就不会动了。而可动的参数一般写在配置文件里面。配置语言的格式一般有一下几种

优点缺点
xml扩展性强,歧义性小对于人来说过于冗长
Json可读性强无法添加注释
yaml可读取强缩进地狱,手动修改时极其容易出现问题

选择Xml

首先Xml的文件不是我们自己生成的,而是机器自己主动生成的。因为我们一般的使用逻辑是

程序生成默认配置文件
人为修改文件
程序读取修改后的结果

对于我们配置人员来说,修改的部分是比较少的,而且由于其极强的拓展性,可以添加许多的注释。所以我打算使用Xml来生成对应的配置文档。而Json由于其修改时容易出错和扩展性的问题,我暂时就不用了。

简单的Xml使用

微软其实已经帮我们封装好了Xml的操控类。这里直接用序列化对象就行了

微软 XML 序列化示例。

测试用例

  public class MyConfigService
  {

      public string Name { get; set; }

      public string Description { get; set; }

      public int Id { get; set; }

      public bool IsEnabled { get; set; }

      public enum MyKeys { Apple,Banana,Pear}

      public MyKeys SettingKey { get; set; }

      public MyConfigService() { }
  }

简单的写

            MyConfigService myConfigService = new MyConfigService() {
                Name = "坤坤",
                Description = "偶像练习生",
                Id = 114514,
                IsEnabled = false,
                SettingKey = MyConfigService.MyKeys.Pear
            };

            var xmlHelper = new XmlSerializer(typeof(MyConfigService));
            StreamWriter xmlWriter = new StreamWriter("MyConfig.xml");
            xmlHelper.Serialize(xmlWriter, myConfigService);
            xmlWriter.Close();

在这里插入图片描述

简单的读

     static void Main(string[] args)
     {
         MyConfigService myConfigService = new MyConfigService()
         {
             Name = "坤坤",
             Description = "偶像练习生",
             Id = 114514,
             IsEnabled = false,
             SettingKey = MyConfigService.MyKeys.Pear
         };

         var xmlHelper = new XmlSerializer(typeof(MyConfigService));
         //StreamWriter xmlWriter = new StreamWriter("MyConfig.xml");
         //xmlHelper.Serialize(xmlWriter, myConfigService);
         //xmlWriter.Close();

         StreamReader xmlReader = new StreamReader("MyConfig.xml");
         var res = xmlHelper.Deserialize(xmlReader);
         Console.WriteLine(JsonConvert.SerializeObject(res));

         Console.WriteLine("运行完成!");
         Console.ReadKey();
     }

在这里插入图片描述

在这里插入图片描述

简单的生成配置

C# XML序列化/反序列化参考

修改配置类

    /// <summary>
    /// 重命名根节点
    /// </summary>
    [XmlRoot("RootTest")]
    public class MyConfigService
    {
        /// <summary>
        /// 重命名,从Name变成extra
        /// </summary>
        [XmlElement("extra")]
        public string Name { get; set; }

        public string Description { get; set; }

        public int Id { get; set; }
        public bool IsEnabled { get; set; }

        public enum MyKeys { Apple,Banana,Pear}

        public MyKeys SettingKey { get; set; }

        /// <summary>
        /// 以Default属性的形式加载到根节点上面
        /// </summary>
        [XmlAttribute()]
        public string Default = "描述";

        public MyConfigService() { }
    }

测试用例

  static void Main(string[] args)
  {
      MyConfigService myConfigService = new MyConfigService()
      {
          Name = "坤坤",
          Description = "偶像练习生",
          Id = 114514,
          IsEnabled = false,
          SettingKey = MyConfigService.MyKeys.Pear
      };

      var xmlHelper = new XmlSerializer(typeof(MyConfigService));
      StreamWriter xmlWriter = new StreamWriter("MyConfig.xml");
      //去掉烦人的命名空间
      XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
      ns.Add("", "");
      xmlHelper.Serialize(xmlWriter, myConfigService,ns);
      xmlWriter.Close();

      //StreamReader xmlReader = new StreamReader("MyConfig.xml");
      //var res = xmlHelper.Deserialize(xmlReader);
      //Console.WriteLine(JsonConvert.SerializeObject(res));

      Console.WriteLine("运行完成!");
      Console.ReadKey();
  }

运行结果对比

在这里插入图片描述

代码逻辑封装

逻辑示意

xml序列化Helper
默认生成
默认读取
读取解析出错覆盖
文件路径是否存在确认

封装好的代码

   public class MyXmlConfigHelper<T>
   {
       public T Setting { get; set; }

       public string FileName { get; set; } = "MyConfig.xml";

       public string DirectoryPath
       {
           get
           {
               var regex = new Regex(@"\\(\w+)\.(\w+)$");
               return regex.Split(FullPath)[0];
           }
       }
       public string DebugPath { get => Directory.GetCurrentDirectory(); }

       public string FullPath { get => DebugPath + "\\" + FileName; }

       public bool IsFileExist { get => File.Exists(FullPath); }

       public bool IsDirectoryExist { get => Directory.Exists(DirectoryPath); }

       public Action<string> ShowMsg { get; set; } = (msg)=>Console.WriteLine(msg);

       public MyXmlConfigHelper()
       {

       }
       public MyXmlConfigHelper(string filename)
       {
           FileName = filename;
           if (!IsDirectoryExist)
           {
               DirectoryInfo directoryInfo = new DirectoryInfo(DirectoryPath);
               directoryInfo.Create();
           }
       }

       public MyXmlConfigHelper(T setting ,string filename):this(filename)
       {
           Setting = setting;
       }

       /// <summary>
       /// 创建文件
       /// </summary>
       public void Init()
       {
           if(IsFileExist)
           {
               try
               {
                   Read();
               }
               catch (Exception ex)
               {
                   ShowMsg(ex.ToString());
                   throw new Exception("文件读取失败!请确认是否配置文件格式是否正确");
               }
           }
           else
           {
               Write();
           }
       }

       /// <summary>
       /// 覆盖文件
       /// </summary>
       public void ReInit()
       {
           ShowMsg("正在覆盖配置文件:" + FullPath);
           Write();
       }
       /// <summary>
       /// 写入配置类
       /// </summary>
       private void Write()
       {
           ShowMsg("正在生成配置文件:" + FullPath);
           var xmlHelper = new XmlSerializer(typeof(T));
           using (StreamWriter xmlWriter = new StreamWriter(FullPath))
           {
               //去掉烦人的命名空间
               XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
               ns.Add("", "");
               xmlHelper.Serialize(xmlWriter, Setting, ns);
               xmlWriter.Close();
           }
       }

       /// <summary>
       /// 读取配置类
       /// </summary>
       private void Read()
       {
           ShowMsg("正在读取配置文件:"+FullPath);
           var xmlHelper = new XmlSerializer(typeof(T));
           using (StreamReader xmlReader = new StreamReader(FullPath))
           {
               
               Setting = (T)xmlHelper.Deserialize(xmlReader);
               xmlReader.Close();
           }
           
       }
   }

测试生成

    static void Main(string[] args)
    {
        var config = new MyConfigService() {
            Name = "小坤",
            Description="爱坤",
            Default = "鲲鲲",
            SettingKey = MyConfigService.MyKeys.Banana,
            Id = 80086,
            IsEnabled = true,
        };

        var xmlHelper = new MyXmlConfigHelper<MyConfigService>(config, "Config\\MyConfig.xml");
 
        xmlHelper.Init();

        Console.WriteLine("运行完成!");
        Console.ReadKey();
    }

在这里插入图片描述
我还做了判断,如果不存在,则生成默认,如果存在,则读取的判断

配置文件格式错误测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用默认值覆盖来解决问题

    static void Main(string[] args)
    {
        var config = new MyConfigService() {
            Name = "小坤",
            Description="爱坤",
            Default = "鲲鲲",
            SettingKey = MyConfigService.MyKeys.Banana,
            Id = 80086,
            IsEnabled = true,
        };

        var xmlHelper = new MyXmlConfigHelper<MyConfigService>(config, "Config\\MyConfig.xml");
        try
        {
            xmlHelper.Init();

        }
        catch (Exception ex)
        {
            //如果出错,则使用默认值覆盖
            Console.WriteLine(ex.ToString());
            xmlHelper.ReInit();

        }

        Console.WriteLine("运行完成!");
        Console.ReadKey();
    }

在这里插入图片描述

配置文件人为修改错误如何解决

解决方案有以下几种

  • 不解决,使用默认值,一直到人为修改回去
  • 手动解决,但是现场人员不一定了解配置信息
  • 重新生成覆盖,但是这样会丢失以前配置的数据
  • 从缓存数据库中读取上传成功运行的代码,回复到最初的状态

理论上来说,第4个是最好的,因为我们现场人员就算修改出现问题了,也能回滚到程序之前的配置。但是C# 默认是没有缓存这个东西的。缓存是需要存在一个地方。我个人认为最好的存储中介就是Sqlite数据库。Sqlite本身体积小,性能强,不需要安装。对于1G以下,100万条以下的数据最好的存储中介。

挖个坑,后面研究一下基于Sqlite的缓存数据库

解决方案

生成两个配置文件,一个是主配置文件,一个是备份配置文件。

程序运行
读取主要+备份
主要+备份都完整
主要覆盖备份
主要破损,备份完整
备份还原主要
主要完整,备份破损
主要+备份都破损
主要备份默认值覆盖

代码

    public class MyXmlConfigAutoHelper<T>
    {
        public T Setting { get; set; }
        public string FileName { get; set; } = "MyConfig.xml";

        public string BackupName
        {
            get
            {
                var regex = new Regex(@"(\w+)\.(\w+)$");
                var filename = regex.Match(FileName).Value;
                var backName = (new Regex(@"\.(\w+)$")).Split(filename)[0];
                var newBackName = backName + "_back";

                return (new Regex(backName)).Replace(FileName, newBackName);
            }
        }

        /// <summary>
        /// 备份
        /// </summary>
        private MyXmlConfigHelper<T> backupXml { get; set; }

        private MyXmlConfigHelper<T> settingXml { get; set; }

        public MyXmlConfigAutoHelper()
        {

        }

        public MyXmlConfigAutoHelper(string fileName)
        {
            FileName = fileName;
        }
        public MyXmlConfigAutoHelper(string fileName, T setting)
        {
            Setting = setting;
            FileName = fileName;
        }

        /// <summary>
        /// 实例化
        /// </summary>
        public void AutoInit()
        {
            settingXml = new MyXmlConfigHelper<T>(Setting, FileName);
            backupXml = new MyXmlConfigHelper<T>(Setting, BackupName);
            //如果备份也损坏了,就GG了
            var settingFlag = true;
            var backupFlag = true;
            try
            {
                settingXml.Init();
            }
            catch (Exception ex)
            {
                Console.WriteLine("主文件读取失败");
                Console.WriteLine(ex.Message);
                settingFlag = false;
            }

            try
            {
                backupXml.Init();
            }
            catch (Exception ex)
            {
                Console.WriteLine("备份文件读取失败");
                Console.WriteLine(ex.Message);
                backupFlag = false;
            }
            Console.WriteLine($"文件完整性:setting[{settingFlag},backup[{backupFlag}]]");

            if (!backupFlag && !settingFlag)
            {
                Console.WriteLine("主要和备份文件完全破损,默认值覆盖");
                backupXml.ReInit();
                settingXml.ReInit();
            }
            else if (!backupFlag)
            {
                Console.WriteLine("备份文件完全破损,主要文件覆盖");
                backupXml.Setting = settingXml.Setting;
                backupXml.ReInit();
            }
            else if (!settingFlag)
            {
                Console.WriteLine("主要文件完全破损,备份文件覆盖");
                settingXml.Setting = backupXml.Setting;
                settingXml.ReInit();
            }
            else
            {
                Console.WriteLine("主要和备份文件正常,主要文件覆盖备份文件");
                backupXml.Setting = settingXml.Setting;
                backupXml.ReInit();
            }
            Setting = settingXml.Setting;
        }

        public void ReInit()
        {
            settingXml = new MyXmlConfigHelper<T>(Setting, FileName);
            backupXml = new MyXmlConfigHelper<T>(Setting, BackupName);
            settingXml.ReInit();
            backupXml.ReInit();
        }
    }

测试用例

        static void Main(string[] args)
        {
            var config = new MyConfigService() {
                Name = "小坤",
                Description="爱坤",
                Default = "鲲鲲",
                SettingKey = MyConfigService.MyKeys.Banana,
                Id = 80086,
                IsEnabled = true,
            };

            var xmlAutoHelper = new MyXmlConfigAutoHelper<MyConfigService>("resource\\Myconfig.xml", config);
            xmlAutoHelper.AutoInit();
            //Console.WriteLine(xmlAutoHelper.BackupName);

            Console.WriteLine("运行完成!");
            Console.ReadKey();
        }

运行结果

由于测试步骤过于复杂,情况比较多,这里就不放截图了。简单来说就是尽可能的使用已有的数据进行还原,如果两个文件都损坏直接使用默认值替换

代码封装总结

    public class MyXmlConfigAutoHelper<T>
  {
      public T Setting { get; set; }
      public string FileName { get; set; } = "MyConfig.xml";

      public string BackupName
      {
          get
          {
              var regex = new Regex(@"(\w+)\.(\w+)$");
              var filename = regex.Match(FileName).Value;
              var backName = (new Regex(@"\.(\w+)$")).Split(filename)[0];
              var newBackName = backName + "_back";

              return (new Regex(backName)).Replace(FileName, newBackName);
          }
      }

      /// <summary>
      /// 备份
      /// </summary>
      private MyXmlConfigHelper<T> backupXml { get; set; }

      private MyXmlConfigHelper<T> settingXml { get; set; }

      public MyXmlConfigAutoHelper()
      {

      }

      public MyXmlConfigAutoHelper(string fileName)
      {
          FileName = fileName;
      }
      public MyXmlConfigAutoHelper(string fileName, T setting)
      {
          Setting = setting;
          FileName = fileName;
      }

      /// <summary>
      /// 实例化
      /// </summary>
      public void AutoInit()
      {
          settingXml = new MyXmlConfigHelper<T>(Setting, FileName);
          backupXml = new MyXmlConfigHelper<T>(Setting, BackupName);
          //如果备份也损坏了,就GG了
          var settingFlag = true;
          var backupFlag = true;
          try
          {
              settingXml.Init();
          }
          catch (Exception ex)
          {
              Console.WriteLine("主文件读取失败");
              Console.WriteLine(ex.Message);
              settingFlag = false;
          }

          try
          {
              backupXml.Init();
          }
          catch (Exception ex)
          {
              Console.WriteLine("备份文件读取失败");
              Console.WriteLine(ex.Message);
              backupFlag = false;
          }
          Console.WriteLine($"文件完整性:setting[{settingFlag},backup[{backupFlag}]]");

          if (!backupFlag && !settingFlag)
          {
              Console.WriteLine("主要和备份文件完全破损,默认值覆盖");
              backupXml.ReInit();
              settingXml.ReInit();
          }
          else if (!backupFlag)
          {
              Console.WriteLine("备份文件完全破损,主要文件覆盖");
              backupXml.Setting = settingXml.Setting;
              backupXml.ReInit();
          }
          else if (!settingFlag)
          {
              Console.WriteLine("主要文件完全破损,备份文件覆盖");
              settingXml.Setting = backupXml.Setting;
              settingXml.ReInit();
          }
          else
          {
              Console.WriteLine("主要和备份文件正常,主要文件覆盖备份文件");
              backupXml.Setting = settingXml.Setting;
              backupXml.ReInit();
          }
          Setting = settingXml.Setting;
      }

      public void ReInit()
      {
          settingXml = new MyXmlConfigHelper<T>(Setting, FileName);
          backupXml = new MyXmlConfigHelper<T>(Setting, BackupName);
          settingXml.ReInit();
          backupXml.ReInit();
      }
  }

  public class MyXmlConfigHelper<T>
  {
      public T Setting { get; set; }

      public string FileName { get; set; } = "MyConfig.xml";

      public string DirectoryPath
      {
          get
          {
              var regex = new Regex(@"\\(\w+)\.(\w+)$");
              return regex.Split(FullPath)[0];
          }
      }
      public string DebugPath { get => Directory.GetCurrentDirectory(); }

      public string FullPath { get => DebugPath + "\\" + FileName; }

      public bool IsFileExist { get => File.Exists(FullPath); }

      public bool IsDirectoryExist { get => Directory.Exists(DirectoryPath); }

      public Action<string> ShowMsg { get; set; } = (msg) => Console.WriteLine(msg);

      public MyXmlConfigHelper()
      {

      }
      public MyXmlConfigHelper(string filename)
      {
          FileName = filename;
          if (!IsDirectoryExist)
          {
              DirectoryInfo directoryInfo = new DirectoryInfo(DirectoryPath);
              directoryInfo.Create();
          }
      }

      public MyXmlConfigHelper(T setting, string filename) : this(filename)
      {
          Setting = setting;
      }

      /// <summary>
      /// 创建文件
      /// </summary>
      public void Init()
      {
          if (IsFileExist)
          {
              try
              {
                  Read();
              }
              catch (Exception ex)
              {
                  ShowMsg(ex.ToString());
                  throw new Exception("文件读取失败!请确认是否配置文件格式是否正确");
              }
          }
          else
          {
              Write();
          }
      }

      /// <summary>
      /// 覆盖文件
      /// </summary>
      public void ReInit()
      {
          ShowMsg("正在覆盖配置文件:" + FullPath);
          Write();
      }
      /// <summary>
      /// 写入配置类
      /// </summary>
      public void Write()
      {
          ShowMsg("正在生成配置文件:" + FullPath);
          var xmlHelper = new XmlSerializer(typeof(T));
          using (StreamWriter xmlWriter = new StreamWriter(FullPath))
          {
              //去掉烦人的命名空间
              XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
              ns.Add("", "");
              xmlHelper.Serialize(xmlWriter, Setting, ns);
              xmlWriter.Close();
          }
      }

      /// <summary>
      /// 读取配置类
      /// </summary>
      public void Read()
      {
          ShowMsg("正在读取配置文件:" + FullPath);
          var xmlHelper = new XmlSerializer(typeof(T));
          using (StreamReader xmlReader = new StreamReader(FullPath))
          {

              Setting = (T)xmlHelper.Deserialize(xmlReader);
              xmlReader.Close();
          }
      }
  }

总结

我这里最后加了个back备份文件,我们平时就修改主要文件的配置即可。如果主要文件损坏,那就备份文件补上。但是这个是主要文件损坏的情况,如果主要文件没损坏,是参数设置错了呢?那我们可以自动生成按照时间戳的备份文件,一次存多个。

  • 主要文件
  • 备份文件-2024-1-6 17:37:20
  • 备份文件-2024-1-6 17:37:30

为了安全考虑的方式是没有上限的。这里就不展开说明了,这里已经写好一个基本的设置文件自动保存,和设置文件自动备份回档的功能,如果想要更高的安全基本可以自己在我的代码上面继续封装。

还有备份文件可以当做缓存文件一样来使用,但是这个是明文存储的。可以自己手动加密一下,反正加密和解密的方法也有很多。可以自己琢磨一下。

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

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

相关文章

Linux系统使用超详细(八)~磁盘管理

目录 一、认识磁盘 二、磁盘运行机制 三、磁盘检查 3.1查找设备名称和分区号 3.1.1使用lsblk命令&#xff1a; 3.1.2使用fdisk命令&#xff1a; 3.1.3使用blkid命令&#xff1a; 3.2检查方向 3.2.1文件系统完整性&#xff1a; 3.2.2磁盘健康状态&#xff1a; 3.2.3磁…

C#,深度优先搜索(DFS)、广度优先搜索(BFS)算法的源代码与数据可视化

概述 下载源代码&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1sLxMT78LVg2dWyXXFvM--w?pwd2kwl 提取码&#xff1a;2kwl --来自百度网盘超级会员V5的分享https://pan.baidu.com/s/1sLxMT78LVg2dWyXXFvM--w?pwd2kwl 深度优先搜索&#xff08;亦称深度优先遍历&a…

uniapp选择android非图片文件的方案踩坑记录

这个简单的问题我遇到下面6大坑&#xff0c;原始需求是选择app如android的excel然后读取到页面并上传表格数据json 先看看效果 uniapp 选择app excel文件读取 1.uniapp自带不支持 uniapp选择图片和视频非常方便自带已经支持可以直接上传和读取 但是选择word excel的时候就出现…

红外传感器(含代码注释)

一.引言 红外传感器是一种能够检测和测量红外光的传感器。由于红外光的特性&#xff0c;红外传感器在许多领域中得到了广泛的应用&#xff0c;如军事、航空航天、医疗、环保、工业控制等。本文将详细介绍红外传感器的原理、应用以及未来发展趋势。 二.红外传感器的工作原理 红外…

Vue3-41-组件- 动态组件 component 标签 和 is 属性 的使用

说明 <component> 标签 有一个 is 属性&#xff0c; 可以给这个 is属性 赋值为一个 组件对象&#xff0c; 这样这个<component> 标签就可以渲染指定的组件对象了。 使用案例 本案例中会 准备两个简单的组件&#xff0c; 在 App.vue 中导入这两个组件&#xff0c;并…

Thonny开发ESP32点灯

简介 ESP32是一款功能强大的低功耗微控制器&#xff0c;由乐鑫&#xff08;Espressif&#xff09;公司开发。它集成了Wi-Fi和蓝牙功能&#xff0c;适用于各种物联网应用。Thonny是一款基于Python的开源集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为MicroPython设计…

SpringBoot学习(六)-SpringBoot整合Shiro

12、Shiro 12.1概述 12.1.1简介 Apache Shiro是一个强大且易用的Java安全框架 可以完成身份验证、授权、密码和会话管理 Shiro 不仅可以用在 JavaSE 环境中&#xff0c;也可以用在 JavaEE 环境中 官网&#xff1a; http://shiro.apache.org/ 12.1.2 功能 Authentication…

【Leetcode】230. 二叉搜索树中第K小的元素

一、题目 1、题目描述 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。 示例1: 输入:root = [3,1,4,null,2], k = 1 输出:1示例2: 输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3提示: 树中…

Supershell反溯源配置

简介 项目地址&#xff1a;https://github.com/tdragon6/Supershell Supershell是一个集成了reverse_ssh服务的WEB管理平台&#xff0c;使用docker一键部署&#xff08;快速构建&#xff09;&#xff0c;支持团队协作进行C2远程控制&#xff0c;通过在目标主机上建立反向SSH隧…

1389 蓝桥杯 二分查找数组元素 简单

1389 蓝桥杯 二分查找数组元素 简单 //C风格解法1&#xff0c;lower_bound(),通过率100% //利用二分查找的方法在有序的数组中查找&#xff0c;左闭右开 #include <bits/stdc.h> using namespace std;int main(){int data[200];for(int i 0 ; i < 200 ; i) data[i] …

Android 15即将到来,或将推出5大新功能特性

Android15 OneUI电池优化 三星最近完成了对其所有设备的稳定版 One UI 6.0 更新的推出&#xff0c;引起了用户的极大兴奋。据新出现的互联网统计数据显示&#xff0c;即将发布的基于 Android 15 的 One UI 7 将通过优化电池和功耗来重新定义用户体验&#xff0c;这是一项具有突…

听GPT 讲Rust源代码--compiler(19)

File: rust/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs 该文件&#xff08;rust/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs&#xff09;是Rust编译器针对MIPS架构上的Linux系统的目标描述文件。它的作用是定义了在这个目标上编译时的一些配置…

商品砍价系统设计原理与实践:技术解析与注意事项

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

Java序列化篇----第一篇

系列文章目录 文章目录 系列文章目录前言一、什么是java序列化,如何实现java序列化?二、保存(持久化)对象及其状态到内存或者磁盘三、序列化对象以字节数组保持-静态成员不保存四、序列化用户远程对象传输前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…

第16课 播放rtsp流

在现实生活中有许多rtsp摄像头&#xff0c;这些摄像头如果能充分利用起来可以生成很多有趣、有用的应用&#xff1a;比如户外互动大屏等。在第4课&#xff0c;我们实现了一个播放器&#xff0c;当时来用它播放rtmp流和mp4时它好象工作的很好。这节课我们就用它来播放rtsp流试试…

物联网产品中,终端、网关、协议、PaaS、SaaS之间的关系

在互联网产品中&#xff0c;经常提到的终端、网关、协议、PaaS、SaaS之间&#xff0c;到底有什么关系呢&#xff1f; 一、基本概念 在百度/其他地方搜集的信息中&#xff0c;对于终端、网关、协议、PaaS、SaaS的解释各有不同&#xff0c;整理如下&#xff1a; 终端&#xff1…

CMU15-445-Spring-2023-Project #1 - Buffer Pool

前置知识&#xff0c;参考上一篇博客&#xff1a;CMU15-445-Spring-2023-Project #1 - 前置知识&#xff08;lec01-06&#xff09; 在存储管理器中实现缓冲池。缓冲池负责将物理页从主内存来回移动到磁盘。它允许 DBMS 支持大于系统可用内存量的数据库。缓冲池的操作对系统中的…

【书生·浦语大模型实战营01】《书生·浦语大模型全链路开源体系》

《书生浦语大模型全链路开源体系》 1. 大模型成为热门关键词 LLM发展时间轴 2. 书生浦语全链条开源开放体系 微调&#xff1a;XTuner 支持全参数微调支持LoRA等低成本微调 评测&#xff1a;OpenCompass 全方位评测&#xff0c;性能可复现80套评测集&#xff0c; 40万道题目…

【大数据】Zookeeper 数据写入与分布式锁

Zookeeper 数据写入与分布式锁 1.数据是怎么写入的2.基于 Zookeeper 实现分布式锁 1.数据是怎么写入的 无论是 Zookeeper 自带的客户端 zkCli.sh&#xff0c;还是使用 Python&#xff08;或者其它语言&#xff09;实现的客户端&#xff0c;本质上都是连接至集群&#xff0c;然…

Linux 上 Nginx 配置访问 web 服务器及配置 https 访问配置过程记录

目录 一、前言说明二、配置思路三、开始修改配置四、结尾 一、前言说明 最近自己搭建了个 Blog 网站&#xff0c;想把网站部署到服务器上面&#xff0c;本文记录一下搭建过程中 Nginx 配置请求转发的过程。 二、配置思路 web项目已经在服务器上面运行起来了&#xff0c;运行的端…