🔧 工具库
Snet.Utility 提供扩展方法与工具类,涵盖工业数据操作、字节处理、网络操作、JSON/XML 序列化及深度对象比较。
包名: Snet.Utility
目标框架: .NET 8.0 / .NET 10.0
依赖项: Newtonsoft.Json 13.0.4, protobuf-net 3.2.56
▶️ 快速开始
说明:
Snet.Utility是Snet.Core的传递依赖。当你安装任何驱动包(如Snet.Modbus)时,它会自动引入。下面的独立安装命令仅在你不使用完整框架时才有需要。
# 独立使用(若已安装 Snet 驱动则无需此步骤)
dotnet add package Snet.Utility
常用扩展方法,对所有对象可用:
using Snet.Utility;
// JSON 序列化
var json = myObject.ToJson(true); // 格式化输出
var obj = json.ToJsonEntity<MyType>(); // 反序列化
// 深度对象比较
var result = expected.Comparer(actual);
Console.WriteLine($"相等: {result.result}, 差异数: {result.difference?.Count}");
// DateTime 格式化
string dateStr = DateTime.Now.ToDateTimeString();
⚙️ 安装
Snet.Utility 是 Snet.Core 的传递依赖。若已安装 Snet.Core,则无需额外安装。
🧠 核心概念
扩展方法
通过 using Snet.Utility 使用:
| 方法 | 描述 |
|---|---|
ToJson(bool indented) |
序列化为 JSON 字符串(Newtonsoft.Json) |
ToJsonEntity<T>() |
反序列化 JSON 字符串为类型对象 |
ToXml() |
序列化为 XML 字符串 |
ToXmlEntity<T>() |
反序列化 XML 字符串为类型对象 |
ToBytes() |
字符串转字节数组(默认 UTF-8) |
ToBytes(Encoding) |
指定编码转字节数组 |
ToDateTimeString() |
DateTime 格式化为 "yyyy-MM-dd HH:mm:ss" |
Comparer<T>(T a, T b, string[]? propertyNames = null) |
深度比较,返回 (bool result, List<Difference>? difference) |
处理器类
| 处理器 | 用途 |
|---|---|
ByteHandler |
字节/字组装、十六进制转换、CRC/LRC 校验 |
NetHandler |
IP 获取、Ping、Telnet、端口检查 |
FileHandler |
文件/文件夹读取、写入、删除、清理 |
FtpHandler |
FTP 上传/下载 |
TimeHandler |
秒表计时、微秒延时 |
XmlHandler |
XML 序列化辅助 |
SvgHandler |
SVG 渲染工具 |
RMAHandler |
资源管理自动化 |
对象比较框架
位于 Snet.Utility.comparer 的递归深度比较引擎:
- 可配置限制的
ComparisonConfig - 单属性自定义验证
- 类型专属比较器
- 忽略模式与排除规则
// 比较两个对象;可选仅比较指定属性
var result = expected.Comparer(actual);
if (!result.result)
foreach (var diff in result.difference)
Console.WriteLine($"{diff.PropertyName}: {diff.Object1Value} != {diff.Object2Value}");
// 仅比较选中属性
var partial = expected.Comparer(actual, new[] { "IpAddress", "Port" });
📚 API 参考
ByteHandler
| 方法 | 描述 |
|---|---|
GetDouble(ushort b3, ushort b2, ushort b1, ushort b0) |
4 个字组装为 double |
GetSingle(ushort high, ushort low) |
2 个字组装为 float |
GetUInt32(ushort high, ushort low) |
2 个字组装为 uint |
GetAsciiBytes(params byte[]/ushort[]) |
数值转 ASCII 字节 |
NetworkBytesToHostUInt16(byte[]) |
大端字节转 ushort |
HexToBytes(string) |
十六进制字符串转字节数组 |
CalculateLrc(byte[]) |
LRC 校验 |
CalculateCrc(byte[]) |
CRC 校验 |
CombineBytes(...) |
拼接两个字节数组 |
calc_modbus_crc(byte[]) |
Modbus CRC16 |
calc_crc_16(ushort polynomial, byte[]) |
可配置多项式的 CRC-16 |
calc_sum_16(byte[]) |
求和校验 |
calc_xor(byte[]) |
异或校验 |
NetHandler
| 方法 | 描述 |
|---|---|
GetIP(IpType ipType) |
获取本机 IPv4/IPv6 地址 |
ClearSamePortProcess(int port) |
结束占用端口的进程 |
Ping(string ip) |
Ping 主机,返回 bool |
Telnet(string ip, int port) |
TCP 连通性检查,返回 bool |
GetUrlIp(string url) |
解析 URL 对应的 IP 地址 |
IsPortInUse(int port) |
检查本地端口是否被占用 |
FileHandler
| 方法 | 描述 |
|---|---|
GetFolderPath(string path, bool create = true) |
获取/创建文件夹路径 |
GetFileName(string path) |
从路径提取文件名 |
FileToString(string path, Encoding? encoding = null, bool removeBom = true) |
读取文件为字符串 |
FileToStringAsync(...) |
异步读取文件为字符串 |
StringToFile(string path, string data, Encoding? encoding = null) |
写入字符串到文件 |
StringToFileAsync(...) |
异步写入字符串到文件 |
ConvertToBinary(string path) |
读取文件为字节数组 |
FileDelete(string path) |
删除文件 |
FolderClear(string path) |
清空文件夹内容 |
RunCmd(string cmd) |
运行 shell 命令 |
CleanHistory() / CleanTempFiles() / CleanCookie() / CleanAll() |
清理辅助 |
TimeHandler
| 方法 | 描述 |
|---|---|
Instance(string sn) |
获取(或创建)命名秒表实例 |
StartRecord() |
启动秒表计时 |
StopRecord() |
停止并返回 (int hours, int minutes, int seconds, int milliseconds) |
DelayUs(double us) |
阻塞式微秒延时 |
💻 代码示例
JSON 序列化往返
using Snet.Utility;
var device = new { Name = "PLC-001", Ip = "192.168.1.100", Port = 502 };
string json = device.ToJson(true);
var restored = json.ToJsonEntity<DeviceConfig>();
深度比较
var diff = oldConfig.Comparer(newConfig);
Console.WriteLine($"相等: {diff.result}\n差异数: {diff.difference?.Count}");
字节操作
byte[] data = { 0x01, 0x02, 0x03, 0x04 };
byte[] checksum = ByteHandler.calc_xor(data); // XOR 校验
float value = ByteHandler.GetSingle(0x4120, 0x0000); // 字转 float
网络检查
bool reachable = NetHandler.Ping("192.168.1.100");
bool telnetOk = NetHandler.Telnet("192.168.1.100", 502);
bool inUse = NetHandler.IsPortInUse(502);
❓ FAQ
1. ToJson 与 System.Text.Json 如何选择?
ToJson() 使用 Newtonsoft.Json 提供便捷调用。对于性能敏感场景,可直接使用 System.Text.Json 配合源生成器。
2. Comparer 是否线程安全?
并发读取安全。若被比较对象可变且在比较期间被修改,结果可能不一致——建议使用不可变快照。
3. ByteHandler 是否支持所有字节序?
字级字节交换(PLC 常用)由 Snet.Core 的 BytesTransformHandler 处理(ABCD/BADC/CDAB/DCBA)。ByteHandler 提供数值组装辅助(GetSingle、GetDouble、GetUInt32)与校验工具。
📅 版本历史
| 日期 | 版本 | 变更 |
|---|---|---|
| 2026-08-02 | — | 与源码对齐:真实 ByteHandler/NetHandler/FileHandler/TimeHandler 方法、Comparer 元组形态、MaxStructDepth |
| 2026-07-23 | — | .NET 8/10。Newtonsoft.Json 13.0.4, protobuf-net 3.2.56。扩展方法,处理器类,对象比较框架。 |
