自由学习记录(28)

C# 中的流(Stream

流(Stream)是用于读取和写入数据的抽象基类

流表示从数据源读取或向数据源写入数据的矢量过程。

C# 中的流类是从 System.IO.Stream 基类派生的,提供了多种具体实现,每种实现都针对不同的数据源或用途。下面是一些常见的流类型及其作用:

流类型一般都被整合成了一个对象既管输入流 也管输出流,基础概念中的Stream也是如此,只不过有输入输出两个细分的类概念而已

1. 流的基础概念

  • 流(Stream):在计算机中表示一种数据的连续流动,可以是从文件、内存、网络或其他设备中读取数据,或者将数据写入这些设备。
  • 输入流(InputStream):用于从数据源读取数据。
  • 输出流(OutputStream):用于将数据写入到数据源。

2. 常见的流类型

  • FileStream:用于从文件读取或向文件写入数据。
  • MemoryStream:用于在内存中读写数据,适用于不需要持久化的临时数据处理
  • NetworkStream:用于网络通信,处理通过网络传输的数据。
  • BufferedStream:为其他流提供缓冲,以提高读取和写入性能。
  • StreamReaderStreamWriter:用于处理文本数据的读写操作,通常与其他流(如 FileStream)一起使用。
  • CryptoStream:用于加密和解密数据流。
  • GZipStreamDeflateStream:用于压缩和解压缩数据流。

3. 内存流(MemoryStream)

  • 作用MemoryStream 是一个特殊的流,它将数据存储在内存中,而不是在磁盘上或其他外部设备上。适用于处理需要快速读写的临时数据。
  • 特点
    • 读写速度快,因为数据存储在内存中。
    • 用于在应用程序内部传输数据或在不需要长期存储数据时使用。
    • 可以使用 ToArray() 方法将内存流中的数据转换为字节数组。
  • 示例用法
    using System;
    using System.IO;class Program
    {static void Main(){// 创建一个内存流using (MemoryStream memoryStream = new MemoryStream()){// 写入数据到内存流byte[] data = new byte[] { 1, 2, 3, 4, 5 };memoryStream.Write(data, 0, data.Length);// 读取数据memoryStream.Position = 0; // 重置位置,以便读取byte[] readData = new byte[data.Length];memoryStream.Read(readData, 0, readData.Length);Console.WriteLine("Read data: " + string.Join(", ", readData));}}
    }
    

4. 文件流(FileStream)

  • 作用FileStream 是用于从文件读取或向文件写入数据的流。它可以处理大文件的读写操作,并支持同步和异步操作。
  • 特点
    • 适用于需要持久化存储数据的场景。
    • 可以通过 FileStream 进行大容量文件的读写操作。
    • 支持指定读取和写入的起始位置及长度。
  • 示例用法
    using System;
    using System.IO;class Program
    {static void Main(){// 创建或打开文件进行写入using (FileStream fileStream = new FileStream("example.txt", FileMode.Create)){byte[] data = new byte[] { 1, 2, 3, 4, 5 };fileStream.Write(data, 0, data.Length);}// 读取文件数据using (FileStream fileStream = new FileStream("example.txt", FileMode.Open)){byte[] readData = new byte[fileStream.Length];fileStream.Read(readData, 0, readData.Length);Console.WriteLine("Read data from file: " + string.Join(", ", readData));}}
    }
    

5. 内存流与文件流的角色

  • 内存流:适用于快速存储和处理临时数据。由于数据存在内存中,操作速度较快。适合数据量较小、需要在程序运行期间使用的数据(如缓存)。
  • 文件流:用于处理需要持久化存储的数据,或者需要对较大文件进行读写的场景。它适合从文件中读取数据或将数据写入到文件的情况。

6. 内存流与文件流的比较

  • 速度:内存流速度较快,因为数据在内存中。文件流通常慢一些,因为数据需要通过磁盘进行读写。
  • 存储:内存流的数据是临时的,只在内存中存在。文件流的数据持久化存储在磁盘中。
  • 使用场景
    • 内存流:适用于处理小到中等大小的数据或需要快速操作的数据,如临时数据的缓存。
    • 文件流:适用于处理大文件或需要长期存储的文件,如日志文件、文档、数据库文件等。

总结

  • 内存流(MemoryStream:在内存中读写数据,适合处理临时数据和高效的数据操作。
  • 文件流(FileStream:用于文件读写,适合需要持久化存储的场景,支持大文件处理。

内存流和序列化

MemoryStream  内存中读写数据,一个流对象

序列化              对象转换为可以存储或传输的格式

结合这两个概念,你可以将对象序列化为字节流,并在内存中操作它们

以下是一些常见的方法来实现内存流序列化:

1. BinaryFormatter 二进制序列化

 .NET 中一个常用的序列化工具,可将对象转换为二进制格式,并将其写入流中。

示例代码:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;[Serializable]
public class MyClass
{public string Name { get; set; }public int Age { get; set; }
}class Program
{static void Main(){// 创建对象MyClass obj = new MyClass { Name = "Alice", Age = 30 };// 将对象序列化到内存流中using (MemoryStream memoryStream = new MemoryStream()){IFormatter formatter = new BinaryFormatter();formatter.Serialize(memoryStream, obj);// 将内存流的字节数组用于其他操作,例如保存到文件或传输byte[] serializedData = memoryStream.ToArray();// 反序列化对象using (MemoryStream readStream = new MemoryStream(serializedData)){MyClass deserializedObj = (MyClass)formatter.Deserialize(readStream);Console.WriteLine($"Name: {deserializedObj.Name}, Age: {deserializedObj.Age}");}}}
}

注意BinaryFormatter 已被标记为不推荐使用,因为它存在安全风险,特别是在处理不受信任的数据时。建议使用其他序列化方法,如 System.Text.JsonXmlSerializer

2. 使用 JsonSerializer 进行 JSON 序列化

如果你希望使用更现代且安全的序列化格式,可以使用 System.Text.Json.JsonSerializer

示例代码:
using System;
using System.IO;
using System.Text.Json;public class MyClass
{public string Name { get; set; }public int Age { get; set; }
}class Program
{static void Main(){// 创建对象MyClass obj = new MyClass { Name = "Alice", Age = 30 };// 将对象序列化为 JSON 格式using (MemoryStream memoryStream = new MemoryStream()){JsonSerializer.Serialize(memoryStream, obj);memoryStream.Position = 0; // 重置流的位置,以便读取数据// 反序列化对象MyClass deserializedObj = JsonSerializer.Deserialize<MyClass>(memoryStream);Console.WriteLine($"Name: {deserializedObj.Name}, Age: {deserializedObj.Age}");}}
}

3. 使用 XmlSerializer 进行 XML 序列化

如果你需要序列化为 XML 格式,可以使用 XmlSerializer

示例代码:
using System;
using System.IO;
using System.Xml.Serialization;public class MyClass
{public string Name { get; set; }public int Age { get; set; }
}class Program
{static void Main(){// 创建对象MyClass obj = new MyClass { Name = "Alice", Age = 30 };// 将对象序列化为 XML 格式using (MemoryStream memoryStream = new MemoryStream()){XmlSerializer serializer = new XmlSerializer(typeof(MyClass));serializer.Serialize(memoryStream, obj);memoryStream.Position = 0; // 重置流的位置,以便读取数据// 反序列化对象MyClass deserializedObj = (MyClass)serializer.Deserialize(memoryStream);Console.WriteLine($"Name: {deserializedObj.Name}, Age: {deserializedObj.Age}");}}
}

总结

  • 使用 BinaryFormatter 进行二进制序列化和反序列化。
  • 使用 System.Text.Json.JsonSerializer 进行 JSON 格式的序列化和反序列化,推荐用于现代应用。
  • 使用 XmlSerializer 进行 XML 格式的序列化和反序列化。

在选择序列化方法时,请根据你的需求和数据的安全性考虑。BinaryFormatter 不推荐用于处理不可信数据,而 System.Text.JsonXmlSerializer 更加安全和现代。

特性(Attributes)

每一个特性实例都是贴在挂了[] 的元素

这个元素可以在运行时通过反射调用特性类实例中的各种成员和方法

这些方法又可以反过来作用于挂[]的元素上,

比如特性挂在了某个类的方法上,那么每次调用这个方法的话

都是经过了挂在这个方法上的特性类实例的处理后,再产生最终结果的

不严谨,有错误的理解,但大致思路是这样的,只是这个处理应该不是在运行时动态的,还会扯到框架什么什么的,只不过目前的水平还深入不下去,目前这样理解也勉强凑合了

自己定义了一个特性类,这个特性类只要被挂在任意的一个元素上面,就会生成一个与这个元素相关联的特性类实例

类和方法的特性互不影响

  • 类上的特性 只会影响类本身,与类中的方法、属性无关。

  • 方法上的特性 只会影响该方法,与类的其他成员无关。

一个元素可以有多个特性。在 C# 中,多个特性可以作用在同一个类、方法、属性等元素上,每个特性会独立存在,且互不影响。

一个继承了 Attribute 的类可以被写成 [] 中的特性语法,并附加到方法、属性、类等代码元素上

当你将特性应用到代码元素时,编译器会将特性实例的信息记录到元数据中,而不会直接在运行时创建该特性实例。 

自建特性类的特性AttributeUsage 的参数

  • AttributeTargets:指定可以应用特性的位置(类、方法、属性等)。

  • AllowMultiple:是否允许同一代码元素上应用多个实例。

  • Inherited:是否允许特性从基类继承。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class MyCustomAttribute : Attribute
{public string Info { get; }public MyCustomAttribute(string info){Info = info;}
}

特性是通过反射获取的,不会直接附加到代码元素实例上。

加上特性之后,只有通过反射机制才能获得该特性的实例。

Type type = typeof(ExampleClass);
var attributes = type.GetCustomAttributes(typeof(MyCustomAttribute), false);
if (attributes.Length > 0)
{// 特性实例MyCustomAttribute myAttr = (MyCustomAttribute)attributes[0];Console.WriteLine($"Name: {myAttr.Name}, Version: {myAttr.Version}");
}

特性(Attributes) ,元编程机制,向代码元素(如类、方法、属性等)附加元数据。

这种元数据可以在运行时通过反射读取,并驱动额外的逻辑行为


特性的原理

  1. 特性是类的实例

    • 特性本质上是从 System.Attribute 派生的类

  2. 特性的声明方式

    • 特性类必须继承自 System.Attribute

    • 特性通常通过 [AttributeUsage] 特性限制它可以应用的位置和次数。

    • 特性可以有构造函数和属性,用于设置参数和配置。


特性如何工作

1. 编译时:将元数据嵌入到程序集

当你在代码中添加一个特性时,例如:

[Serializable]
public class MyClass { }

编译器会在程序集的元数据中为 MyClass 记录 Serializable 特性。

2. 运行时:通过反射读取特性

你可以在运行时通过反射读取特性的信息,并基于这些信息执行特定操作。


特性的创建与使用

1. 自定义特性

以下是自定义特性的示例:

using System;[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class MyCustomAttribute : Attribute
{public string Name { get; }public int Version { get; }public MyCustomAttribute(string name, int version){Name = name;Version = version;}
}
2. 应用特性

将特性应用到类或方法上:

[MyCustomAttribute("ExampleClass", 1)]
public class Example
{[MyCustomAttribute("ExampleMethod", 2)]public void TestMethod(){Console.WriteLine("Hello from TestMethod");}
}
3. 读取特性

通过反射读取特性的信息:

using System;
using System.Reflection;class Program
{static void Main(){// 获取类的特性Type type = typeof(Example);var classAttributes = type.GetCustomAttributes<MyCustomAttribute>();foreach (var attr in classAttributes){Console.WriteLine($"Class: {type.Name}, Name: {attr.Name}, Version: {attr.Version}");}// 获取方法的特性MethodInfo method = type.GetMethod("TestMethod");var methodAttributes = method.GetCustomAttributes<MyCustomAttribute>();foreach (var attr in methodAttributes){Console.WriteLine($"Method: {method.Name}, Name: {attr.Name}, Version: {attr.Version}");}}
}

输出:

Class: Example, Name: ExampleClass, Version: 1
Method: TestMethod, Name: ExampleMethod, Version: 2

为什么特性可以实现“奇奇怪怪”的功能?

1. 编译器的内置支持

许多特性(如 [Serializable], [Obsolete])在编译器中被特殊处理:

  • [Serializable]:提示编译器生成支持序列化的代码。
  • [Obsolete]:在编译时发出警告或错误,提醒使用者该代码已经过时。
2. 框架和库通过特性扩展功能

特性可以驱动框架的运行行为。例如:

  • ASP.NET Core 使用特性(如 [HttpGet], [HttpPost])标记控制器的路由规则。
  • Entity Framework 使用特性(如 [Key], [Required])定义数据库表的映射规则。
  • JSON 序列化库 使用特性(如 [JsonIgnore], [JsonProperty])控制对象的序列化行为。
3. 特性允许插入元编程逻辑

特性是实现 AOP(面向切面编程) 的核心工具,可以在特定代码执行时插入行为。例如:

  • [Log] 特性可以自动记录方法的调用信息。
  • [Validate] 特性可以在方法调用前校验参数。

总结:特性的工作流程

  1. 声明特性:通过继承 System.Attribute 定义自定义特性。
  2. 应用特性:将特性以 [AttributeName] 的形式附加到代码元素上。
  3. 元数据存储:编译器将特性信息存储在程序集的元数据中。
  4. 读取特性:运行时通过反射获取元数据,执行逻辑。

特性看似只是加了个 [],实际上背后依赖了 C# 的强大编译器支持和运行时反射机制,使得它能够驱动复杂的逻辑,成为元编程的重要工具。

Encoding.UTF8.GetString()

将字节数组(byte[])解码为字符串。

两种重载


1. 方法签名

重载1:直接传入字节数组
public string GetString(byte[] bytes);
重载2:指定范围
public string GetString(byte[] bytes, int index, int count);
  • 参数说明
    • byte[] bytes: 要解码的字节数组。
    • int index: 哪个索引开始解码。
    • int count: 解码的字节数。

2. 用法示例

解码整个字节数组
using System;
using System.Text;class Program
{static void Main(){byte[] utf8Bytes = { 72, 101, 108, 108, 111 }; // "Hello" 的 UTF-8 编码string result = Encoding.UTF8.GetString(utf8Bytes);Console.WriteLine(result); // 输出: Hello}
}
解码部分字节
using System;
using System.Text;class Program
{static void Main(){byte[] utf8Bytes = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 }; // "Hello World" 的 UTF-8 编码// 解码从索引 6 开始的 5 个字节string result = Encoding.UTF8.GetString(utf8Bytes, 6, 5);Console.WriteLine(result); // 输出: World}
}

3. 参数的关键点

参数合法性
  • 字节数组 (byte[]) 必须是合法的 UTF-8 数据
    • 数组中包含非法或不完整的 UTF-8 字节序列,GetString 会抛出异常或替换为 Unicode 替代字符(通常是 )。
  • 索引和长度合法性
    • indexcount 必须满足:
      • index >= 0
      • count >= 0
      • index + count <= bytes.Length
    • 否则会抛出 ArgumentOutOfRangeException
常用场景
  • 解码整个字节数组:Encoding.UTF8.GetString(bytes)
  • 解码部分数据(如网络流数据或文件流数据的片段):Encoding.UTF8.GetString(bytes, index, count)

4. 为什么有两种重载?

  • 第一种重载适合解码完整的字节数组,简单直接。
  • 第二种重载提供灵活性,允许你仅解码字节数组的一部分,这在处理大文件或流式数据时非常有用。

5. 总结

  • 第一种重载(整个字节数组):GetString(byte[] bytes)
    解码完整数组,常见于静态数据的解码。
  • 第二种重载(部分字节数组):GetString(byte[] bytes, int index, int count)
    解码字节数组的指定部分,适合处理流式数据或分块操作。

fs.Write() 

FileStream 类提供,将数据写入文件。

文件流基于字节bytes

所有参数都是必需的,并且没有提供默认值

参数定义了写入的数据以及写入的范围,具体如下:

public override void Write(byte[] array, int offset, int count);
  1. byte[] array:写入文件的数据

  2. int offset:写入数据的起始索引( array[offset] 开始写入)

  3. int count:

    • 指定bytes数组 中写入的字节数。
    • 这个参数可以限制实际写入的数据长度,即使字节数组长度大于 count,也只会写入指定数量的字节。

示例代码

using System;
using System.IO;class Program
{static void Main(){// 创建字节数据byte[] data = new byte[] { 65, 66, 67, 68, 69 }; // 对应 ASCII 字符 A, B, C, D, E// 打开文件流(会覆盖现有内容)using (FileStream fs = new FileStream("example.txt", FileMode.Create, FileAccess.Write)){// 写入 data 数组中的前 3 个字节(A, B, C)fs.Write(data, 0, 3);}Console.WriteLine("写入完成!");}
}
输出到 example.txt 的内容
ABC

关键点补充

为什么不提供默认参数?

设计上,fs.Write() 是低级别的 I/O 方法,用于操作任意二进制数据。它的三个参数控制了写入的范围和数据来源,以下是设计理念:

  1. 灵活性offsetcount 允许你仅写入字节数组的一部分,而不是整个数组。
  2. 效率:你可以通过精确控制写入范围来优化性能,避免不必要的字节拷贝。
  3. 防止错误:如果默认写入整个数组,可能导致意外写入多余数据。

如何简化操作?

大多数常见的用法可以显式写成:fs.Write(data, 0, data.Length);

使用 BinaryWriter

BinaryWriter 是一个更高层的封装,简化了写入数据的操作,无需明确指定 offsetcount。它会直接将完整的字节数组写入文件:

using (var fs = new FileStream("example.txt", FileMode.Create, FileAccess.Write))
using (var writer = new BinaryWriter(fs))
{byte[] data = new byte[] { 65, 66, 67 }; // ABCwriter.Write(data); // 自动写入整个数组
}
使用 StreamWriter(适用于文本数据)

如果处理的是文本而不是二进制数据,StreamWriter 更适合,它完全隐藏了底层字节操作:

using (var writer = new StreamWriter("example.txt"))
{writer.Write("Hello, World!"); // 写入文本
}
byte[] array
  • 文件流操作是以字节为单位,需要将任何数据(如文本、数字、图像)转换为字节数组。
  • 常见的转换方法:
    • 字符串 转换为字节数组Encoding.UTF8.GetBytes(string)
    • 数值类型 转换为字节数组:BitConverter.GetBytes(int)
offsetcount
  • 通过 offsetcount 参数可以选择性地从字节数组中提取一部分数据写入文件。
  • 示例:
    byte[] data = { 65, 66, 67, 68, 69 }; // A, B, C, D, E
    fs.Write(data, 2, 2); // 从索引 2 开始写入 2 个字节 -> 写入 "CD"
    
性能优化
  • 数据量较大,使用 fs.Write() 尽量批量写入而不是逐字节写入
  • 能减少 I/O 操作次数,提升性能

常见错误

  1. 数组越界

    • 如果 offset + count > array.Length,会抛出 ArgumentException
    • 在使用前检查数组长度以避免错误:
      if (offset + count > data.Length)throw new ArgumentException("指定的范围超出了数组长度!");
      
  2. 流未打开或已关闭

    • 如果文件流在调用 Write() 时已关闭,ObjectDisposedException 会被抛出
  3. 权限不足

    • 如果文件流是只读模式(FileAccess.Read,会抛出 NotSupportedException

移动会把文件夹里的所有东西一起移动过去

File.ReadAllLines()

File.ReadAllText()

File.Delete()

File.Copy()

File.Replace()

 Application.dataPath

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

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

相关文章

Redis3——线程模型与数据结构

Redis3——线程模型与数据结构 本文讲述了redis的单线程模型和IO多线程工作原理&#xff0c;以及几个主要数据结构的实现。 1. Redis的单线程模型 redis6.0之前&#xff0c;一个redis进程只有一个io线程&#xff0c;通过reactor模式可以连接大量客户端&#xff1b;redis6.0为了…

Elasticsearch Serverless 现已正式发布

作者&#xff1a;来自 Elastic Yaru Lin 基于全新无状态&#xff08;stateless&#xff09;架构的 Elasticsearch Serverless 现已正式发布。它采用完全托管方式&#xff0c;因此你可以快速启动项目而无需操作或升级&#xff0c;并且可以使用最新的向量搜索和生成式 AI 功能。 …

Android CoordinatorLayout:打造高效交互界面的利器

目录 一、CoordinatorLayout 介绍及特点 二、使用方法 2.1 创建 CoordinatorLayout 布局 2.2 添加需要协调的子视图 2.3 自定义 Behavior 三、结语 相关推荐 在Android开发中&#xff0c;面对复杂多变的用户界面需求&#xff0c;CoordinatorLayout以其强大的交互管理能力…

基于Java Springboot旅游攻略APP且微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…

多模态大语言模型的对比

简介 文章主要对比了包括 VideoLLaMA 2 、CogVLM2-video 、MiniCPM-V等模型 目前主流的多模态视觉问答大模型&#xff0c;大部分采用视觉编码器、大语言模型、图像到文本特征的投影模块 目录 简介1. VideoLLaMA 21.1 网络结构1.2 STC connector具体的架构 2. MiniCPM-V 2.62.…

Android渗透环境配置教程

工具 模拟器 ADB brew install android-platform-tools set import cert # cer 证书转为 pem 证书 openssl x509 -inform DER -in cacert.der -out cacert.pem# 获取证书的 hash 值 hash$(openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -n 1)# 将 pem…

Microi吾码|.NET、VUE快速搭建项目,低代码便捷开发教程

Microi吾码&#xff5c;VUE快速搭建项目&#xff0c;低代码便捷开发教程 一、摘要二、Microi吾码介绍2.1 功能介绍2.2 团队介绍2.3 上线项目案例 三、VUE中使用Microi吾码3.1 前期了解3.2 创建第一个低代码应用3.3 接口API使用说明3.4 引擎界面可视化配置&#xff0c;生成API3.…

常见Linux命令(详解)

文章目录 常见Linux命令文件目录类命令pwd 打印当前目录的绝对路径ls 列出目录内容cd 切换路径mkdir 建立目录rmdir 删除目录touch 创建空文件cp 复制文件或目录rm 移除文件或者目录mv 移动文件与目录或重命名cat 查看文件内容more 文件分屏查看器less 分屏显示文件内容head 显…

AI - 如何构建一个大模型中的Tool

AI - 如何构建一个大模型中的Tool 大家好&#xff01;今天我们聊聊一个有趣的技术问题&#xff1a;什么是工具&#xff08;Tool&#xff09;&#xff0c;如何使用聊天模型调用工具&#xff0c;以及如何将工具的输出传递给聊天模型。我们还是基于LangChain来进行讨论&#xff0…

【测试工具JMeter篇】JMeter性能测试入门级教程(四):JMeter中BeanShell内置方法使用

一、什么是BeanShell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似);BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简…

MyBatis异常体系中ErrorContext和ExceptionFactory原理分析

&#x1f3ae; 作者主页&#xff1a;点击 &#x1f381; 完整专栏和代码&#xff1a;点击 &#x1f3e1; 博客主页&#xff1a;点击 文章目录 exceptions包分包设计ExceptionFactory类介绍为什么使用工厂不是直接new呢&#xff1f;【统一的异常处理机制】【异常的封装与转化】【…

白鹿 Hands-on:消除冷启动——基于 Amazon Lambda SnapStart 轻松打造 Serverless Web 应用(二)

文章目录 前言一、前文回顾二、在 Lambda 上运行2.1、查看 Amazon SAM template2.2、编译和部署到 Amazon Lambda2.3、功能测试与验证 三、对比 Snapstart 效果四、资源清理五、实验总结总结 前言 在这个环节中&#xff0c;我们将延续《白鹿 Hands-on&#xff1a;消除冷启动——…

Spring Shell如何与SpringBoot集成并快速创建命令行界面 (CLI) 应用程序

Spring Shell 介绍 Spring Shell 是一个强大的工具&#xff0c;可用于构建命令行应用程序&#xff0c;提供了简单的方式来创建和管理交互式 CLI。它适合那些希望通过命令行与 Java 应用程序进行交互的开发者&#xff0c;尤其是在需要自动化、交互式输入或与 Spring 生态系统集…

齐护机器人ModbusRTU RS485转TTL通信模块与ESP32 Arduino通信可Mixly的图形化编程Scratch图形化编程

齐护机器人ModbusRTU RS485-TTL通信模块 一、概念理解 Modbus协议是一种由Modicon公司&#xff08;现为施耐德电气Schneider Electric&#xff09;于1979年发表的网络通信协议&#xff0c;旨在实现可编辑逻辑控制器&#xff08;PLC&#xff09;之间的通信。 1.1 什么是Mod…

K8S版本和istio版本的对照关系

版本对照关系 下载地址1 下载地址2

vue-cli创建项目报错:command failed: npm install --loglevel error

网上解决方法有很多&#xff0c;对于我都没用。 最后用这个方法起了作用&#xff1a; 尝试将npm源设置为HTTP&#xff0c;慎用&#xff0c;可能不安全 npm config set registry http://registry.npm.taobao.org/ 改为http就顺利创建项目了。

数据结构自测题6

第7章 图 自测卷解答 一、单选题&#xff08;每题1分&#xff0c;共16分&#xff09; &#xff08; C &#xff09;1. 在一个图中&#xff0c;所有顶点的度数之和等于图的边数的 倍。 A&#xff0e;1/2 B. 1 C. 2 D. 4 &#xff08; B &#xff09;2. 在一个有向图中&#xff0…

洛谷P1305 新二叉树(c嘎嘎)

题目链接&#xff1a;P1305 新二叉树 - 洛谷 | 计算机科学教育新生态 题目难度&#xff1a;普及 刷题心得&#xff1a;做了几道这种类型的题都不用建树就可以解决&#xff0c;基本上还是利用好树的结构&#xff0c;例如这道题求前序序列&#xff08;根左右&#xff09;是可以用…

(18)时间序列预测之FiLM

没错&#xff0c;就是看电影 文章目录 前言1. 问题描述2. 创新之处3. 贡献 一、时间序列在legende - fourier域的表示1. 勒让德投影2. 傅里叶变换 二、 模型结构1. LPU: Legendre Projection Unit2. FEL: Frequency Enhanced Layer3. 多尺度专家机制的混合 二、实验结果长时预测…

Linux | Linux的开机启动流程

对于linux系统的初学者来说&#xff0c;理解并掌握linux系统启动流程能够使你够深入的理解linux系统&#xff0c;还可以通过系统的启动过程来分析问题解决问题。 Linux开机启动的流程如下图 power on 开机 post自检&#xff08;检查一部分大的硬件&#xff09; BIOS&#xf…