自由学习记录(28)
C# 中的流(Stream
)
流(Stream
)是用于读取和写入数据的抽象基类。
流表示从数据源读取或向数据源写入数据的矢量过程。
C# 中的流类是从 System.IO.Stream
基类派生的,提供了多种具体实现,每种实现都针对不同的数据源或用途。下面是一些常见的流类型及其作用:
流类型一般都被整合成了一个对象既管输入流 也管输出流,基础概念中的Stream也是如此,只不过有输入输出两个细分的类概念而已
1. 流的基础概念
- 流(Stream):在计算机中表示一种数据的连续流动,可以是从文件、内存、网络或其他设备中读取数据,或者将数据写入这些设备。
- 输入流(InputStream):用于从数据源读取数据。
- 输出流(OutputStream):用于将数据写入到数据源。
2. 常见的流类型
- FileStream:用于从文件读取或向文件写入数据。
- MemoryStream:用于在内存中读写数据,适用于不需要持久化的临时数据处理。
- NetworkStream:用于网络通信,处理通过网络传输的数据。
- BufferedStream:为其他流提供缓冲,以提高读取和写入性能。
- StreamReader 和 StreamWriter:用于处理文本数据的读写操作,通常与其他流(如
FileStream
)一起使用。 - CryptoStream:用于加密和解密数据流。
- GZipStream 和 DeflateStream:用于压缩和解压缩数据流。
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.Json
或 XmlSerializer
。
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.Json
和 XmlSerializer
更加安全和现代。
特性(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) ,元编程机制,向代码元素(如类、方法、属性等)附加元数据。
这种元数据可以在运行时通过反射读取,并驱动额外的逻辑行为。
特性的原理
-
特性是类的实例
-
特性本质上是从
System.Attribute
派生的类
-
-
特性的声明方式:
-
特性类必须继承自
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]
特性可以在方法调用前校验参数。
总结:特性的工作流程
- 声明特性:通过继承
System.Attribute
定义自定义特性。 - 应用特性:将特性以
[AttributeName]
的形式附加到代码元素上。 - 元数据存储:编译器将特性信息存储在程序集的元数据中。
- 读取特性:运行时通过反射获取元数据,执行逻辑。
特性看似只是加了个 []
,实际上背后依赖了 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 替代字符(通常是�
)。
- 数组中包含非法或不完整的 UTF-8 字节序列,
- 索引和长度合法性:
index
和count
必须满足: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);
-
byte[] array
:写入文件的数据 -
int offset
:写入数据的起始索引(array[offset]
开始写入) -
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 方法,用于操作任意二进制数据。它的三个参数控制了写入的范围和数据来源,以下是设计理念:
- 灵活性:
offset
和count
允许你仅写入字节数组的一部分,而不是整个数组。 - 效率:你可以通过精确控制写入范围来优化性能,避免不必要的字节拷贝。
- 防止错误:如果默认写入整个数组,可能导致意外写入多余数据。
如何简化操作?
大多数常见的用法可以显式写成:fs.Write(data, 0, data.Length);
使用 BinaryWriter
BinaryWriter
是一个更高层的封装,简化了写入数据的操作,无需明确指定 offset
和 count
。它会直接将完整的字节数组写入文件:
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)
- 字符串 转换为字节数组:
offset
和 count
- 通过
offset
和count
参数可以选择性地从字节数组中提取一部分数据写入文件。 - 示例:
byte[] data = { 65, 66, 67, 68, 69 }; // A, B, C, D, E fs.Write(data, 2, 2); // 从索引 2 开始写入 2 个字节 -> 写入 "CD"
性能优化
- 数据量较大,使用
fs.Write()
尽量批量写入而不是逐字节写入 - 能减少 I/O 操作次数,提升性能
常见错误
-
数组越界:
- 如果
offset + count > array.Length
,会抛出ArgumentException
。 - 在使用前检查数组长度以避免错误:
if (offset + count > data.Length)throw new ArgumentException("指定的范围超出了数组长度!");
- 如果
-
流未打开或已关闭:
- 如果文件流在调用
Write()
时已关闭,ObjectDisposedException
会被抛出。
- 如果文件流在调用
-
权限不足:
- 如果文件流是只读模式(
FileAccess.Read
),会抛出NotSupportedException
。
- 如果文件流是只读模式(
移动会把文件夹里的所有东西一起移动过去
File.ReadAllLines()
File.ReadAllText()
File.Delete()
File.Copy()
File.Replace()
Application.dataPath
相关文章:

自由学习记录(28)
C# 中的流(Stream) 流(Stream)是用于读取和写入数据的抽象基类。 流表示从数据源读取或向数据源写入数据的矢量过程。 C# 中的流类是从 System.IO.Stream 基类派生的,提供了多种具体实现,每种实现都针对…...

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

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

【和春笋一起学C++】OpenCV中数组和指针运用实例
前言:前面学习了数组和指针在C中的处理原理,本文通过自己编写一个图像处理的函数实例来加深对数组和指针的理解。为什么是图像处理呢,因为图像数据是一个二维矩阵,相当于一个二维数组,前面学习了一维数组,现…...

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

React 路由(React Router):在 React 应用中管理路由
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《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),指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作。 XXS的分类 反射型XSS存储型XSSDOM型XSS 原理 反射型XSS 接收用户提交的访问者的姓名࿰…...

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

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

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

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

深度学习-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框架中,你可以使用不同的模板来创建应用程序。你提到的这几个项目类型主要针对的是Qt的不同模块和用户界面技术。下面我将分别解释这些项目类型的区别: 根据你提供的信息,以下是每个项目模板的详细描述和适用场景: Qt Widgets…...

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

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

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

Hbase应用案例 随机号码生成
Hbase应用案例1 随机号码生成 在Hbase中插入如下格式的数据,数据内容随机生成 名称示例说明phonenumber158randomrowkey,号码dnum199randomcolumn,另一位通话者lengthrandomcolumn,时长valuerandomcolumn,接收或拨打…...

论文阅读——量子退火Experimental signature of programmable quantum annealing
摘要:量子退火是一种借助量子绝热演化解决复杂优化问题的通用策略。分析和数值证据均表明,在理想化的封闭系统条件下,量子退火可以胜过基于经典热化的算法(例如模拟退火)。当前设计的量子退火装置的退相干时间比绝热演…...

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验二----网络分析(超超超详细!!!)
相信实验一大家已经完成了,对Arcgis已进一步熟悉了,现在开启第二个实验 ArcMap实验--网络分析 目录 ArcMap实验--网络分析 1.1 网络分析介绍 1.2 实验内容及目的 1.2.1 实验内容 1.2.2 实验目的 2.2 实验方案 2.3 实验流程 2.3.1 实验准备 2.3.2 空间校正…...

go语言 Pool实现资源池管理数据库连接资源或其他常用需要共享的资源
go Pool Pool用于展示如何使用有缓冲的通道实现资源池,来管理可以在任意数量的goroutine之间共享及独立使用的资源。这种模式在需要共享一组静态资源的情况(如共享数据库连接或者内存缓冲区)下非 常有用。如果goroutine需要从池里得到这些资…...

mysql一个事务最少几次IO操作
事务的IO操作过程 开始事务:用户发起一个事务,例如执行START TRANSACTION;,此时事务开始。读取和修改数据:用户读取和修改数据时,InnoDB首先从Buffer Pool查找所需的数据页。如果数据页不在Buffer Pool中,…...

运输层总结
运输层协议:端到端协议 面向连接的传输控制协议 TCP无连接的用户数据报协议 UDP - 主要任务:为相 互通信的应用进程 提供 逻辑通信服务 - 屏蔽:运输层向高层用户 屏蔽 了下面网络核心的细节(如网络拓扑、所采用 的路由选择协议等…...

【嵌套查询】.NET开源 ORM 框架 SqlSugar 系列
.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

React 前端框架1
一、React 简介 (一)什么是 React React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开源并维护。它采用了组件化的开发思想,允许开发者将复杂的 UI 拆分成一个个独立、可复用的小组件,就如同搭积木一般&am…...

【真正离线安装】Adobe Flash Player 32.0.0.156 插件离线安装包下载(无需联网安装)
网上很多人声称并提供的flash离线安装包是需要联网才能安装成功的,其实就是在线安装包,而这里提供的是真正的离线安装包,无需联网即可安装成功。 点击下面地址下载离线安装包: Adobe Flash Player 32.0.0.156 for IE Adobe Fla…...

数据采集时,不同地区的动态IP数据质量有什么差异?
在数据采集的广阔世界中,动态IP扮演着至关重要的角色。它们不仅帮助我们突破地域限制,还能够提供多样化的数据来源。但是,不同地区的动态IP在数据质量上是否存在差异呢?本文将探讨这一问题,并为您提供实用的见解。 动…...