当前位置: 首页 > news >正文

C#Object类型的索引,序列化和反序列化

前言

最近在编写一篇关于标准Mes接口框架的文章。其中有一个非常需要考究的内容时如果实现数据灵活和可使用性强。因为考虑数据灵活性,所以我一开始选取了Object类型作为数据类型,Object作为数据Value字段,String作为数据Key字段,形态与Dic的模式比较相似。但是在实际使用过程中,由于Object可以存储任意类型,但是显性类型指向Object,Type指向数据源类型。但是在进行Xml和Json序列化时候就出现了问题,Json和Xml无法序列化Object,这个非常合理,因为Object类型是没有指向的,序列化和反序列化时,无法知道你的Object类型指向哪一种类型。因为这个原因,所以我自己根据Json和XMl的数据格式编写了一套序列化和反序列化的规则。

1.方法说明

我预先设计了一个为MesProcessData的类,他里面包含一个string的索引字段,和Object的存储字段。那么我Object字段中存储的时一组新的MesProcessData的数组,在每个新的MesProcessData中又可以存储新的数据或者数组。这个方式参考来自于C#的索引机制。C# 中 . 运算符主要用于访问类或对象的成员、命名空间中的类型,对象的名字代表的是每一级的索引。那么MesName就是我所属变量的索引,object就是索引的值。在类型判断中,我们可以通过判断Object的Type是否为Array的形式去判断Object是否存储的是MesProcessData的类对象,如果是则继续递归查找,如果不是则判断当前的MesName是否是我所需要的索引。这些内容说的非常绕口,所以下面实际使用代码演示一下

2.使用方式

//将数据为Header,Body,Return的数据存储在Top中List<MesProcessData> Message = new List<MesProcessData>();List<MesProcessData> Head = new List<MesProcessData>();Head.Add(new MesProcessData { MesName = "MESSAGENAME", MesValue = dynamic.AddressInterface });Head.Add(new MesProcessData { MesName = "TRANSACTIONID", MesValue = MesApp.Instance.Const.NowTime.ToString("yyyyMMddHHmmssffff") + number });Head.Add(new MesProcessData { MesName = "MESSAGEID", MesValue = number.ToString() });Head.Add(new MesProcessData { MesName = "REPLYSUBJECTNAME", MesValue = MesApp.Instance.MyMesConfig.MesAddress + ":" + MesApp.Instance.MyMesConfig.CustomerA.Port });Message.Add(new MesProcessData { MesName = "Header", MesValue = Head.ToArray() });Message.Add(new MesProcessData { MesName = "Body", MesValue = datas.ToArray() });List<MesProcessData> MessageReturn = new List<MesProcessData>();MessageReturn.Add(new MesProcessData { MesName = "ReturnCode", MesValue = "" });MessageReturn.Add(new MesProcessData { MesName = "ReturnMessage", MesValue = "" });Message.Add(new MesProcessData { MesName = "Return", MesValue = MessageReturn.ToArray() });MesProcessData Top = new MesProcessData();Top.MesName = "Message";Top.MesValue = Message.ToArray();
//根据上面代码存入的数据,查找数据中索引为Header.MESSAGENAME的值
string MesInterface = ProcessData.FindValueByPath(new string[] { "Header", "MESSAGENAME" }, 0).ToString();
using System;
using System.Collections.Generic;
using System.Linq;namespace Const
{public class MesProcessData{public string MesName { get; set; } = "";public object MesValue { get; set; }/// <summary>/// 根据指定路径找到对应的值/// </summary>/// <param name="path">数组路径,从下一级参数开始</param>/// <param name="index">当前使用的路径开始编号。仅在函数递归时使用</param>/// <returns></returns>public object FindValueByPath(string[] path, int index = 0){if (index >= path.Length){return this.MesValue;}if (this.MesValue is Array){Array array = this.MesValue as Array;List<MesProcessData> datas = array.OfType<MesProcessData>().ToList();foreach (MesProcessData child in datas){if (child.MesName == path[index]){return child.FindValueByPath(path, index + 1);}}}return null;}/// <summary>/// 根据指定路径来修改参数值/// </summary>/// <param name="path">数组路径,从下一级参数开始</param>/// <param name="newValue">新的值</param>/// <param name="index">当前使用的路径开始编号。仅在函数递归时使用 </param>/// <returns></returns>public MesProcessData ModifyValueByPath(string[] path, object newValue, int index = 0){if (index >= path.Length){this.MesValue = newValue;return this;}if (this.MesValue is Array array){List<MesProcessData> datas = array.OfType<MesProcessData>().ToList();foreach (MesProcessData child in datas){if (child.MesName == path[index]){// 递归修改下一级节点child.ModifyValueByPath(path, newValue, index + 1);}}}return this;}public string ObjectToString(){if (this.MesValue is string strArray){return strArray;}else{return null;}}public List<MesProcessData> ObjectToData(){List<MesProcessData> datas = new List<MesProcessData>();if (this.MesValue is Array){Array array = this.MesValue as Array;datas = array.OfType<MesProcessData>().ToList();}return datas;}}}

3.序列化和反序列化

参照上面的内容我们可以分析,当判断为数组时,我们进行递归,直到递归到没有数组值为止,那么Name作为Key,MesValue作为Value。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;namespace Model
{internal class MesJson{public static T DeserializeObject<T>(string json){return JsonConvert.DeserializeObject<T>(json);}public static string SerializeObject<T>(T Data){return JsonConvert.SerializeObject(Data);}/// <summary>/// 反序列化为 MesProcessData/// </summary>/// <param name="Json"></param>/// <returns></returns>public static MesProcessData DeserializeJson(string Json){// 解析 JSON 字符串为 JObjectJObject jsonObject = JObject.Parse(Json);MesProcessData data = new MesProcessData();// 开始遍历解析 JSON 对象data = TraverseJsonNodes(jsonObject);return data;}private static MesProcessData TraverseJsonNodes(JObject jsonObject){MesProcessData data = new MesProcessData();data.MesName = jsonObject.Path;if (jsonObject.Count == 1){data.MesValue = jsonObject.First.ToString();}List<MesProcessData> datas = new List<MesProcessData>();foreach (var item in jsonObject){if (item.Value.Type == JTokenType.String){MesProcessData Jdata = new MesProcessData();Jdata.MesName = item.Key.ToString();Jdata.MesValue = item.Value.ToString();datas.Add(Jdata);}elsedatas.Add(TraverseJsonNodes((JObject)item.Value));}data.MesValue = datas.ToArray();return data;}private static readonly object Lock = new object();/// <summary>/// 将传入的 Object 对象序列化为 JSON 格式/// </summary>/// <param name="obj"></param>/// <returns></returns>public static string SerializeToJson(object obj){try{lock (Lock){StringBuilder sb = new StringBuilder();SerializeObject(obj, sb);return sb.ToString();}}catch (Exception ex){MesLog.Error("Mes Json序列化失败:" + ex.ToString());return "";}}private static void SerializeObject(object obj, StringBuilder sb){if (obj == null){sb.Append("null");return;}Type type = obj.GetType();if (type.IsPrimitive || type == typeof(string)){sb.Append(JsonValue(obj));return;}if (type.IsArray){sb.Append("[");Array array = (Array)obj;for (int i = 0; i < array.Length; i++){if (i > 0){sb.Append(",");}SerializeObject(array.GetValue(i), sb);}sb.Append("]");return;}sb.Append("{");sb.AppendLine();FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);bool first = true;foreach (FieldInfo field in fields){object fieldValue = field.GetValue(obj);if (fieldValue == null){continue;}if (!first){sb.Append(",");sb.AppendLine();}first = false;sb.Append($"\"{field.Name}\": ");SerializeObject(fieldValue, sb);}sb.AppendLine();sb.Append("}");}private static string JsonValue(object obj){if (obj == null){return "null";}if (obj is string str){return $"\"{EscapeString(str)}\"";}if (obj is bool boolValue){return boolValue.ToString().ToLower();}if (obj is char){return $"\"{obj}\"";}return obj.ToString();}private static string EscapeString(string str){StringBuilder sb = new StringBuilder();foreach (char c in str){if (c == '\\' || c == '"'){sb.Append('\\');}sb.Append(c);}return sb.ToString();}}
}
using JOJO.Mes.Const;
using JOJO.Mes.Log;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;namespace JOJO.Mes.Model
{internal class MesXml{/// <summary>/// 不带反馈的发送信息/// </summary>/// <param name="socket"></param>/// <param name="obj"></param>public static async void SendObjectAsXml(Socket socket, string xmlString){try{byte[] xmlBytes = Encoding.UTF8.GetBytes(xmlString);await Task.Run(() =>{// 通过Socket发送数据socket.Send(xmlBytes, 0, xmlBytes.Length, SocketFlags.None);});}catch (Exception ex){MesLog.Error("发送不带反馈的Socket数据失败:" + ex.ToString());}}public static T DeserializeObject<T>(string Xml){XmlSerializer serializer = new XmlSerializer(typeof(T));StringReader stringReader = new StringReader(Xml);T deserializedData = (T)serializer.Deserialize(stringReader);stringReader.Dispose();return deserializedData;}/// <summary>/// 反序列化为MesProcessData/// </summary>/// <param name="Xml"></param>/// <returns></returns>public static MesProcessData DeserializeXml(string Xml){XmlDocument xmlDoc = new XmlDocument();xmlDoc.LoadXml(Xml);MesProcessData data = new MesProcessData();data = TraverseNodes(xmlDoc.DocumentElement);return data;}static MesProcessData TraverseNodes(XmlNode node){MesProcessData data1 = new MesProcessData();data1.MesName = node.Name;if (node.HasChildNodes){if (node.FirstChild.NodeType == XmlNodeType.Text){data1.MesValue = node.InnerText;return data1;}List<object> datas = new List<object>();foreach (XmlNode childNode in node.ChildNodes){datas.Add(TraverseNodes(childNode));}data1.MesValue = datas.ToArray();}else{data1.MesValue = node.InnerText;}return data1;}private static readonly object Lock = new object();/// <summary>/// 将传入的Object对象序列化为XML格式/// </summary>/// <param name="obj"></param>/// <returns></returns>public static string SerializeToXml(object obj){try{lock (Lock){StringWriter stringWriter = new StringWriter();using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter)){//添加输入对象的头,xmlWriter.WriteStartDocument();FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);foreach (FieldInfo field in fields){object fieldValue = field.GetValue(obj);string fieldName = field.Name;if (fieldValue != null){Type valueType = fieldValue.GetType();if (valueType.IsPrimitive || valueType == typeof(string) || !valueType.IsArray){if (field.Name.Contains("MesValue")){xmlWriter.WriteValue(fieldValue);}else if (field.Name.Contains("MesName")){xmlWriter.WriteStartElement(fieldValue.ToString());continue;}else{xmlWriter.WriteStartElement(field.FieldType.Name.ToString());xmlWriter.WriteValue(fieldValue);xmlWriter.WriteEndElement();continue;}xmlWriter.WriteEndElement();}else if (valueType.IsArray){Array array = (Array)fieldValue;foreach (object item in array){if (item != null){string subXml = SerializeToXml(item);xmlWriter.WriteRaw(subXml);}}}else{string subXml = SerializeToXml(fieldValue);xmlWriter.WriteRaw(subXml);string xml = xmlWriter.ToString();}}}//xmlWriter.WriteEndElement();xmlWriter.WriteEndDocument();}return stringWriter.ToString();}}catch (Exception ex){MesLog.Error("序列化XML失败:" + ex.ToString());return "";}}private static XElement RecursiveProcess(XElement element){List<XElement> newChildren = new List<XElement>();foreach (XElement child in element.Elements()){XElement name = child.Element("MesName");XElement value = child.Element("MesValue");if (name != null && value != null){XElement newElement;if (value.HasElements){// 如果Value有子元素,递归处理XElement processedValue = RecursiveProcess(value);newElement = new XElement(name.Value, processedValue.Nodes());}else{newElement = new XElement(name.Value, value.Value);}newChildren.Add(newElement);}else{if (child.Nodes().Count() > 1){// 如果没有Name和Value,继续递归处理子元素XElement recursivelyProcessedChild = RecursiveProcess(child);newChildren.Add(recursivelyProcessedChild);}else{newChildren.Add(child);}}}element.RemoveAll();element.Add(newChildren);return element;}}}

4.结论

这种方式限定了数据的规则,但是核心原理是一致的。在序列化中,对于可读序列化而言,只有值和数组值的区分。所以我们在控制Object类型序列化时也是参考这个方式,判断是否为数组即可,如果数据格式跟我的不一样的话,那么可以使用反射的形式。例如在一个类中有部分字段为Object类型,那么我们使用反射的形式,将json映射Object中,同样我们也需要判断Json中的Object是否为数组,不是可以直接赋值,是的话则需要递归转换再赋值。将字段中的Object转换为Json也是同理,判断是否为数组,不是则直接转换,是则递归转换。

相关文章:

C#Object类型的索引,序列化和反序列化

前言 最近在编写一篇关于标准Mes接口框架的文章。其中有一个非常需要考究的内容时如果实现数据灵活和可使用性强。因为考虑数据灵活性&#xff0c;所以我一开始选取了Object类型作为数据类型&#xff0c;Object作为数据Value字段&#xff0c;String作为数据Key字段&#xff0c…...

Unity3D项目开发中的资源加密详解

前言 在Unity3D游戏开发中&#xff0c;保护游戏资源不被非法获取和篡改是至关重要的一环。资源加密作为一种有效的技术手段&#xff0c;可以帮助开发者维护游戏的知识产权和安全性。本文将详细介绍Unity3D项目中如何进行资源加密&#xff0c;并提供相应的技术详解和代码实现。…...

微调Qwen2:7B模型,加入未知信息语料

对于QWen2这样的模型,在微调的时候,语料的投喂格式满足ChatML这样的格式!!! OpenAI - ChatML: 下面是ChatML格式的介绍: https://github.com/openai/openai-python/blob/release-v0.28.0/chatml.mdhttps://github.com/openai/openai-python/blob/release-v0.28.0/chat…...

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端&#xff1a; sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端&#xff1a; sudo systemctl start ssh贰、配置SSH&#xff08;可跳过&#xff09; 配置文件 …...

【理论】测试开发工程师进阶路线

一、腾讯与阿里的质量保证服务参考 阿里云效测试能力与架构 腾讯 WeTest 测试能力全景图 二、测试开发技术体系 1.用户端测试&#xff1a; Web/App 测试 Web/App 自动化测试 用户端专项测试 用户端安全测试 2.服务端测试&#xff1a; 接口协议与 Mock 接口自动化测试 服务端…...

【BQ3568HM开发板】如何在OpenHarmony上通过校园网的上网认证

引言 前面已经对BQ3568HM开发板进行了初步测试&#xff0c;后面我要实现MQTT的工作&#xff0c;但是遇到一个问题&#xff0c;就是开发板无法通过校园网的认证操作。未认证的话会&#xff0c;学校使用的深澜软件系统会屏蔽所有除了认证用的流量。好在我们学校使用的认证系统和…...

動態住宅IP提升網站訪問成功率

動態住宅IP通常與普通家庭用戶的網路連接相關聯。這種IP地址的特點在於&#xff0c;它是動態變化的&#xff0c;用戶在每次連接時可能會獲得不同的IP地址。這與靜態IP形成了鮮明對比&#xff0c;後者在連接期間保持不變。傳統上&#xff0c;IP地址分為住宅IP和數據中心IP兩類。…...

2024年博客之星主题创作|2024年蓝桥杯与数学建模年度总结与心得

引言 2024年&#xff0c;我在蓝桥杯编程竞赛和数学建模竞赛中投入了大量时间和精力&#xff0c;这两项活动不仅加深了我对算法、数据结构、数学建模方法的理解&#xff0c;还提升了我的解决实际问题的能力。从蓝桥杯的算法挑战到数学建模的复杂应用&#xff0c;我在这些竞赛中…...

Spring Boot/MVC

一、Spring Boot的创建 1.Spring Boot简化Spring程序的开发,使用注解和配置的方式开发 springboot内置了tomact服务器 tomact:web服务器,默认端口号8080,所以访问程序使用8080 src/main/java:Java源代码 src/main/resource:静态资源或配置文件,存放前端代码(js,css,html) s…...

由于请求的竞态问题,前端仔喜提了一个bug

在平常的开发过程中&#xff0c;你可能会遇到这样一个bug。 测试&#xff1a;我在测一个输入框搜索的功能时&#xff0c;告诉你通过输入框输入的内容&#xff0c;和最终通过输入内容搜索出来的结果对不上。 前端&#xff1a;我是通过调用后端接口拿到的数据&#xff0c;这明显…...

【Day25 LeetCode】贪心Ⅲ

一、贪心Ⅲ 1、加油站 134 这道题直接想法是采用二重循环暴力搜索&#xff0c;简单粗暴但是会超时&#xff0c;是因为以每个点为起点最坏的情况可能都要遍历完全部的序列&#xff0c;有大量重复的操作&#xff0c;那有没有优化的地方呢&#xff1f;有一个结论&#xff1a;如果…...

蓝桥杯练习日常|递归-进制转换

未完待续&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c; 目录 蓝桥云课760数的计算 一、递归 题目&#xff1a; 我的解题代码&#xff1a; 二、进制转换 任意进制转十进制&#xff1a; 十进制转换为其他进制&#xff1a; 进制蓝桥杯题目…...

AI Agent:深度解析与未来展望

一、AI Agent的前世&#xff1a;从概念到萌芽 &#xff08;一&#xff09;早期探索 AI Agent的概念可以追溯到20世纪50年代&#xff0c;早期的AI研究主要集中在简单的规则系统上&#xff0c;这些系统的行为是确定性的&#xff0c;输出由输入决定。随着时间的推移&#xff0c;…...

《SwinIR:使用Swin-Transformer图像恢复》学习笔记

paper&#xff1a;2108.10257 GitHub&#xff1a;GitHub - JingyunLiang/SwinIR&#xff1a; SwinIR&#xff1a; 使用 Swin Transformer 进行图像修复 &#xff08;官方仓库&#xff09; 目录 摘要 1、Introduction 2、Related Work 2.1 图像修复 2.2 视觉Transformer…...

如何在Nginx服务器上配置访问静态文件目录并提供文件下载功能

引言 在搭建网站的过程中&#xff0c;我们经常需要让访客通过URL直接访问或下载存储在服务器特定目录下的静态文件。本文将详细介绍如何在Nginx服务器环境中配置一个名为"download"的文件目录&#xff0c;以便用户能够通过浏览器访问并下载其中的手册和其他文档。 …...

ansible自动化运维实战--script、unarchive和shell模块(6)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件&#xff0c;其提供了一…...

理解深度学习pytorch框架中的线性层

文章目录 1. 数学角度&#xff1a; y W x b \displaystyle y W\,x b yWxb示例 2. 编程实现角度&#xff1a; y x W T b \displaystyle y x\,W^T b yxWTb3. 常见错误与易混点解析4. 小结参考链接 在神经网络或机器学习的线性层&#xff08;Linear Layer / Fully Connect…...

电路研究9.2——合宙Air780EP使用AT指令

这里正式研究AT指令的学习了&#xff0c;之前只是接触的AT指令&#xff0c;这里则是深入分析AT指令了。 软件的开发方式&#xff1a; AT&#xff1a;MCU 做主控&#xff0c;MCU 发 AT 命令给模组的开发方式&#xff0c;模组仅提供标准的 AT 固件&#xff0c; 所有的业务控制逻辑…...

Qt数据库相关操作

目录 一、前言 二、类与接口介绍 1.连接管理类 2.数据操作类 3.数据模型类 4.其它类 三、主要操作流程 1.示例 2.绑定参数 3.事务操作 一、前言 要在Qt中操作数据库&#xff0c;首先要安装对应的数据库&#xff0c;还要确保安装了Qt SQL模块。使用MySQL时&#xff0…...

2025-01-22 Unity Editor 1 —— MenuItem 入门

文章目录 1 Editor 文件夹2 MenuItem3 使用示例3.1 打开网址3.2 打开文件夹3.3 Menu Toggle3.4 Menu 代码复用3.5 MenuItem 激活与失活4 代码示例 1 Editor 文件夹 ​ Editor 文件夹是 Unity 中的特殊文件夹&#xff0c;Unity 中所有编辑器相关的脚本都需要放置在其中&#xf…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...