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

自由学习记录(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

相关文章:

自由学习记录(28)

C# 中的流&#xff08;Stream&#xff09; 流&#xff08;Stream&#xff09;是用于读取和写入数据的抽象基类。 流表示从数据源读取或向数据源写入数据的矢量过程。 C# 中的流类是从 System.IO.Stream 基类派生的&#xff0c;提供了多种具体实现&#xff0c;每种实现都针对…...

操作系统、虚拟化技术与云原生01

操作系统基础 操作系统定义 OS声明了软件怎么调用硬件&#xff0c;同时支持人机交互 人机交互的过程&#xff1a; shell是人机交互转换的虚拟环境&#xff0c;内核只能识别0、1组成的数据流&#xff0c;底层资源只能识别电流的变化 操作系统的组成 1. 进程管理 进程定义&#x…...

linux的挂卸载

挂卸载操作 在 Linux 系统中&#xff0c;挂载&#xff08;mount&#xff09;和卸载&#xff08;umount&#xff09;是管理文件系统和存储设备的核心操作。通过这两个操作&#xff0c;我们可以将设备&#xff08;如硬盘、光盘、U盘等&#xff09;或网络文件系统的内容集成到系统…...

【和春笋一起学C++】OpenCV中数组和指针运用实例

前言&#xff1a;前面学习了数组和指针在C中的处理原理&#xff0c;本文通过自己编写一个图像处理的函数实例来加深对数组和指针的理解。为什么是图像处理呢&#xff0c;因为图像数据是一个二维矩阵&#xff0c;相当于一个二维数组&#xff0c;前面学习了一维数组&#xff0c;现…...

Maya 中创建游戏角色的头发,并将其导出到 Unreal Engine 5

这段视频教程讲解了如何在 Maya 中创建游戏角色的头发&#xff0c;并将其导出到 Unreal Engine 5 中&#xff0c;重点是如何处理头发的物理模拟和材质。 作者 Andrew Giovannini 首先展示了一个已完成的带物理模拟的头发模型&#xff0c;并介绍了他自己的游戏行业背景。然后&a…...

React 路由(React Router):在 React 应用中管理路由

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

SAP-CPI组件Transformation介绍之Converter

1.配置CSV to XML Converter Field Description XML Schema 选择Select按钮,选择合适 XSD 文件. 或者可以选择 Upload from File System 系统中查找合适的XML文件....

Laravel 代理收益排行榜

创建了一个收入表 CREATE TABLE income_logs (id int(11) unsigned NOT NULL AUTO_INCREMENT,order_id int(11) NOT NULL COMMENT 订单ID,type int(11) NOT NULL DEFAULT 0 COMMENT 类型 0 支出 1收入,user_id int(11) NOT NULL COMMENT 消费者用户,price decimal(10,2) NOT…...

LeetCode hot100面试背诵版(自用)

点击题目可以跳转到LeetCode 哈希 两数之和 public int[] twoSum(int[] nums, int target) {int lengthnums.length;int[] ans new int[2];for (int i 0; i <length-1 ; i) {for (int j i1; j < length; j) {if(nums[i]nums[j]target){ans[0]i;ans[1]j;}}}return an…...

常见的Web安全漏洞——XSS

概念 跨站脚本攻击(XSS&#xff09;&#xff0c;指攻击者通过篡改网页&#xff0c;嵌入恶意脚本程序&#xff0c;在用户浏览网页时&#xff0c;控制用户浏览器进行恶意操作。 XXS的分类 反射型XSS存储型XSSDOM型XSS 原理 反射型XSS 接收用户提交的访问者的姓名&#xff0…...

liteflow 架构详解

LiteFlow 是一个轻量级的、高性能的流程编排框架&#xff0c;主要用于解决复杂业务流程的编排问题。它提供了一种简单而强大的方式来定义和执行复杂的业务流程。下面是 LiteFlow 的架构详解&#xff1a; 核心概念 组件&#xff08;Component&#xff09;&#xff1a;是流程中…...

国产麒麟操作系统上运行LabVIEW

LabVIEW 目前并没有官方支持直接在国产麒麟操作系统&#xff08;Kylin OS&#xff09;上运行。LabVIEW 是由美国国家仪器公司&#xff08;NI&#xff09;开发的软件&#xff0c;主要面向 Windows 和 Linux 操作系统。麒麟操作系统虽然基于 Linux&#xff0c;但其内核和一些软件…...

【C语言】结构体(一)

一&#xff0c;是什么 结构体就是一些值的集合&#xff0c;这些值称为成员变量。 结构体的每个成员可以是不同类型的变量。说到集合&#xff0c;数组也是集合&#xff0c;但是不同的是数组只能是相同类型元素的集合。 二&#xff0c;结构体的声明 struct tag {   member1;…...

C++《set与map》

在之前我们已经学习了解了CSTL当中的string和vector等容器&#xff0c;现在我们已经懂得了这些容器提供的接口该如何使用&#xff0c;并且了解了这些容器的底层结构。接下来我们在本篇当中将继续学习STL内的容器set与map&#xff0c;在此这两个容器与我们之前学习的容器提供的成…...

深度学习-52-AI应用实战之基于Yolo8的目标检测自动标注

文章目录 1 YOLOv81.1 YOLOV8的不同版本1.2 可检测类别1.3 数据说明1.4 网络结构1.5 算法核心步骤2 目标检测的基本原理2.1 安装yolov8(cpu版本)2.2 图片检测2.3 视频检测2.4 自动标注2.5 保存标注结果3 参考附录1 YOLOv8 YOLOv8是一种前沿的计算机视觉技术,它基于先前YOLO版…...

【Elasticsearch】05-DSL查询

1. 查询所有 es最多只支持查询1万条数据。 # 查询所有 GET /items/_search {"query": {"match_all": {}} }2. 叶子查询 全文检索 会对结果进行相关度打分。 # 检索单个字段 GET /items/_search {"query": {"match": {"name&…...

qml项目创建的区别

在Qt框架中&#xff0c;你可以使用不同的模板来创建应用程序。你提到的这几个项目类型主要针对的是Qt的不同模块和用户界面技术。下面我将分别解释这些项目类型的区别&#xff1a; 根据你提供的信息&#xff0c;以下是每个项目模板的详细描述和适用场景&#xff1a; Qt Widgets…...

.NET8/.NETCore 依赖注入:自动注入项目中所有接口和自定义类

.NET8/.NETCore 依赖接口注入&#xff1a;自动注入项目中所有接口和自定义类 目录 自定义依赖接口扩展类&#xff1a;HostExtensions AddInjectionServices方法GlobalAssemblies 全局静态类测试 自定义依赖接口 需要依赖注入的类必须实现以下接口。 C# /// <summary>…...

Flutter:city_pickers省市区三级联动

pubspec.yaml city_pickers插件地址 自己用的GetBuilder页面模板 cupertino_icons: ^1.0.8 # 省市区城市选择 city_pickers: ^1.3.0编辑地址页面&#xff1a;controller class AddressEditController extends GetxController {AddressEditController();Future<Result?>…...

Kafka-Connect自带示例

一、上下文 《Kafka-Connect》中已经阐述了Kafka-Connect的理论知识&#xff0c;为了更生动的理解它&#xff0c;我们今天通过官方的一个小例子来感受下它的妙用。 二、创建topic kafka-topics --create --topic connect-test --bootstrap-server cdh1:9092 --partitions 2 -…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

2025-05-08-deepseek本地化部署

title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek&#xff1a;小白也能轻松搞定&#xff01; 如何给本地部署的 DeepSeek 投喂数据&#xff0c;让他更懂你 [实验目的]&#xff1a;理解系统架构与原…...

JavaScript 标签加载

目录 JavaScript 标签加载script 标签的 async 和 defer 属性&#xff0c;分别代表什么&#xff0c;有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...

Ansible+Zabbix-agent2快速实现对多主机监控

ansible Ansible 是一款开源的自动化工具&#xff0c;用于配置管理&#xff08;Configuration Management&#xff09;、应用部署&#xff08;Application Deployment&#xff09;、任务自动化&#xff08;Task Automation&#xff09;和编排&#xff08;Orchestration&#xf…...