.Net_比对Json文件是否一致

简介

  • 该方法用于比较两个Json文件是否完全一致,仅考虑内容
  • 若两个文件中的内容只是顺序不一致,内容是一样的,那么也代表这两个文件是相等的

实现代码

  • 调用
using CompareJsonFiles;Console.WriteLine("================= 输入信息 ===================");Console.WriteLine("请输入源Json文件路径:");
var sourcePath = Console.ReadLine();Console.WriteLine($"{Environment.NewLine}请输入目标Json文件路径:");
var targetPath = Console.ReadLine();Console.WriteLine($"{Environment.NewLine}您输入的源路径为:{sourcePath},目标路径为:{targetPath}");Console.WriteLine($"================= 输入信息 =================== {Environment.NewLine}");CompareJsonHelper.CompareJsonFiles(sourcePath?.Trim(), targetPath?.Trim());
  • 实现
using Newtonsoft.Json.Linq;namespace CompareJsonFiles;/// <summary>
/// 比对Json文件的帮助类
/// </summary>
public static class CompareJsonHelper
{/// <summary>/// 比较两个JSON文件的内容/// </summary>/// <param name="sourcePath">源文件</param>/// <param name="targetPath">目标文件</param>public static void CompareJsonFiles(string? sourcePath, string? targetPath){if (!IsExistForJsonFile(sourcePath, targetPath)){return;}// 加载并解析JSON文件var json1 = JToken.Parse(File.ReadAllText(sourcePath));var json2 = JToken.Parse(File.ReadAllText(targetPath));// 标准化JSON结构var normalizedSourceJson = NormalizeJson(json1);var normalizedTargetJson = NormalizeJson(json2);// 比较JSON内容var differences = FindDifferences(normalizedSourceJson, normalizedTargetJson, string.Empty);// 输出差异if (differences.Count == 0){Console.WriteLine("======================== 两个文件内容一致!==============================");}else{Console.WriteLine("============================= 两个文件存在以下差异:=================================");foreach (var diff in differences){Console.WriteLine(diff);}}}/// <summary>/// 监测源文件和目标文件是不是Json文件/// </summary>/// <param name="sourcePath"></param>/// <param name="targetPath"></param>/// <returns></returns>private static bool IsExistForJsonFile(string? sourcePath, string? targetPath){if (string.IsNullOrWhiteSpace(sourcePath)){Console.WriteLine("错误信息:源文件路径不能为空");return false;}if (string.IsNullOrWhiteSpace(targetPath)){Console.WriteLine("错误信息:目标文件路径不能为空");return false;}if (!System.IO.File.Exists(sourcePath)){Console.WriteLine("错误信息:源文件不存在");return false;}if (!System.IO.File.Exists(targetPath)){Console.WriteLine("错误信息:目标文件不存在");return false;}if (Path.GetExtension(sourcePath) != ".json"){Console.WriteLine("错误信息:源文件不是Json文件");return false;}if (Path.GetExtension(targetPath) != ".json"){Console.WriteLine("错误信息:目标文件不是Json文件");return false;}return true;}/// <summary>/// 标准化JSON结构以便比较/// </summary>/// <param name="token"></param>/// <returns></returns>private static JToken NormalizeJson(JToken token){switch (token.Type){case JTokenType.Object:var sortedObject = new JObject();var properties = token.Children<JProperty>().ToList();properties.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.Ordinal));foreach (var prop in properties){sortedObject.Add(prop.Name, NormalizeJson(prop.Value));}return sortedObject;case JTokenType.Array:var sortedArray = new JArray(token.Select(NormalizeJson).OrderBy(t => t.ToString()));return sortedArray;default:return token.DeepClone();}}/// <summary>/// 查找两个JSON之间的差异/// </summary>/// <param name="source"></param>/// <param name="target"></param>/// <param name="path"></param>/// <returns></returns>private static List<string> FindDifferences(JToken source, JToken target, string path){var differences = new List<string>();if (source.Type != target.Type){differences.Add($"路径 {path} 类型不同: {source.Type}{target.Type}");return differences;}switch (source.Type){case JTokenType.Object:foreach (var property in ((JObject)source).Properties()){if (!((JObject)target).TryGetValue(property.Name, out JToken? tryTargetValue)){differences.Add($"路径 {path}.{property.Name} 在第二个文件中不存在");continue;}differences.AddRange(FindDifferences(property.Value, tryTargetValue, $"{path}.{property.Name}"));}foreach (var property in ((JObject)target).Properties()){if (!((JObject)source).TryGetValue(property.Name, out _)){differences.Add($"路径 {path}.{property.Name} 在第一个文件中不存在");}}break;case JTokenType.Array:var arraySource = source as JArray;var arrayTarget = target as JArray;for (var i = 0; i < Math.Max(arraySource?.Count ?? 0, arrayTarget?.Count ?? 0); i++){if (i >= arraySource?.Count || i >= arrayTarget?.Count){differences.Add($"路径 {path}[{i}] 数组长度不一致");continue;}differences.AddRange(FindDifferences(arraySource![i], arrayTarget![i], $"{path}[{i}]"));}break;default:if (!JToken.DeepEquals(source, target)){differences.Add($"路径 {path} 值不同: {source}{target}");}break;}return differences;}
}

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

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

相关文章

Android OpenGLES2.0开发(九):图片滤镜

“当你改变想法的时候&#xff0c;记得也要改变你的世界。”——诺曼文森特皮尔 Android OpenGLES开发&#xff1a;EGL环境搭建Android OpenGLES2.0开发&#xff08;一&#xff09;&#xff1a;艰难的开始Android OpenGLES2.0开发&#xff08;二&#xff09;&#xff1a;环境搭…

易语言OCR证件照文字识别

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

指针练习题15道【C语言】

1.利用指针变量将一个数组中的数据反向输出。 声明&#xff1a; void work1(int *, int); // 声明反向遍历 void work1_1(int *, int); // 声明正向遍历实现&#xff1a; // 利用指针变量将一个数组中的数据反向输出&#xff0c;反向遍历 void work1( int *p,int len) {p (…

单节点calico性能优化

在单节点上部署calicov3273后&#xff0c;发现资源占用 修改calico以下配置是资源消耗降低 1、因为是单节点&#xff0c;没有跨节点pod网段组网需要&#xff0c;禁用overlay方式网络(ipip&#xff0c;vxlan),使用route方式网络 配置calico-node的环境变量 CALICO_IPV4POOL_I…

openjdk17 从C++视角看 String的intern的jni方法JVM_InternString方法被gcc编译器连接

symbols-unix 文件部分内容 JVM_IHashCode JVM_InitClassName JVM_InitStackTraceElement JVM_InitStackTraceElementArray JVM_InitializeFromArchive JVM_InternString 要理解在 symbols-unix 文件中包含 JVM_InternString 方法的原因&#xff0c;我们需要从构建过程、符号…

在 Spring Boot 3 中实现基于角色的访问控制

基于角色的访问控制 (RBAC) 是一种有价值的访问控制模型,可增强安全性、简化访问管理并提高效率。它在管理资源访问对安全和运营至关重要的复杂环境中尤其有益。 我们将做什么 我们有一个包含公共路由和受限路由的 Web API。受限路由需要数据库中用户的有效 JWT。 现在用户…

K8s HPA的常用功能介绍

Kubernetes 的 Horizontal Pod Autoscaler (HPA) 是一种自动扩展功能&#xff0c;用于根据资源使用情况&#xff08;如 CPU、内存等&#xff09;或自定义指标&#xff0c;动态调整 Pod 的副本数量&#xff0c;从而保证应用的性能和资源利用率。 以下是 HPA 的常用功能介绍&…

电子系统中用于降噪的接地

当接地系统中存在EMI、RFI 或由焊机、变速驱动器、电器等引起的电脉冲等干扰时&#xff0c;它们会在中性线和接地之间产生共模噪声&#xff0c;可能会影响电子设备。 国家电气规范 (NEC) 允许安装隔离接地插座 (IG)&#xff0c;即磁轭和接地端子之间没有连接。轭是插座后面的金…

SmartX分享:SMTX ZBS 中 RDMA 技术简介

目录 背景如何实现存储网络是什么TCP/IPRDMARDMA 工作原理RDMA 的实现方案 ZBS 支持 RDMA 的要求 参考 背景 我们清楚&#xff0c;分布式存储将利用网络作不同设备的互联。最基础的如TCP/IP的IP SAN&#xff0c;进阶的有FC SAN、IB等等。 SmartX 支持 10G以上的TCP/IP网络作为…

【人工智能数学基础】——深入详解贝叶斯理论:掌握贝叶斯定理及其在分类和预测中的应用

深入详解贝叶斯理论&#xff1a;掌握贝叶斯定理及其在分类和预测中的应用 贝叶斯理论&#xff08;Bayesian Theory&#xff09;是概率论和统计学中的一个重要分支&#xff0c;它以托马斯贝叶斯&#xff08;Thomas Bayes&#xff09;命名&#xff0c;主要关注如何根据新的证据更…

使用JustAuth实现gittee登录

使用JustAuth实现gittee登录 登录流程&#xff1a; 点击 Github 图标时&#xff0c;调用 handleGiteeLogin获取 Gitee 登录地址并跳转Gitee 授权后&#xff0c;后端进行相关的验证登录等成功后回调到gitee填的回调地址 1.添加依赖 <dependency><groupId>me.zhy…

矩阵的基本知识

例题1&#xff1a;求矩阵最小值&#xff0c;和其所在的行和列 #include<stdio.h> int main() { int arr[10][10]; int g; scanf("%d",&g); int m,n,i,r c; for(i0;i<g;i) { scanf("%d %d",&m,&…

《Vue3实战教程》5:响应式基础

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》 响应式基础​ API 参考 本页和后面很多页面中都分别包含了选项式 API 和组合式 API 的示例代码。现在你选择的是 组合式 API。你可以使用左侧侧边栏顶部的“API 风格偏好”开关在 API 风格之间切换。 声明响应式状态…

【后端面试总结】深入解析进程和线程的区别

在操作系统和并发编程中&#xff0c;进程和线程是两个核心概念。它们各自承担着不同的职责&#xff0c;并在多任务处理中发挥着关键作用。本文将从定义、特性、应用场景以及优缺点等多个方面对进程和线程进行详细对比&#xff0c;帮助读者深入理解它们之间的区别。 一、进程和…

QT网络(二):TCP通信

传输层概念 传输控制协议&#xff08;transmission control protocol&#xff0c;TCP&#xff09;是一种被大多数 Internet 网络协议用于数据传输的底层网络协议&#xff0c;它是可靠的、面向流和连接的传输协议&#xff0c;特别适合用于连续数据传输。 应用层在网络模型中的…

【记录50】uniapp安装uview插件,样式引入失败分析及解决

SassError: Undefined variable: "$u-border-color". 表示样式变量$u-border-color没定义&#xff0c;实际是定义的 首先确保安装了scss/sass 其次&#xff0c;根目录下 app.vue中是否全局引入 <style lang"scss">import /uni_modules/uview-ui/in…

std::async 和 std::packaged_task

0、背景 在现代 C 中&#xff0c;std::async 和 std::packaged_task 是两个非常重要的工具&#xff0c;能够帮助我们更好地处理并发和异步操作。它们分别代表了异步执行任务的两种不同的方式&#xff0c;但都可以有效地将任务的执行从主线程或调用线程中分离出来&#xff0c;以…

windows上安装Redis

下载&#xff1a;https://github.com/tporadowski/redis&#xff08;官方不提供windows版&#xff09; 配置文件里设置密码&#xff1a;requirepass 123456 添加服务的命令&#xff1a; redis-server --service-install redis.windows-service.conf --loglevel verbose (--serv…

TypeScript 与 JavaScript

文章目录 一、为 JavaScript 库添加类型定义(一)什么是类型定义文件(.d.ts 文件)(二)手动编写类型定义和使用现有类型定义(如 DefinitelyTyped)手动编写类型定义使用现有类型定义(如 DefinitelyTyped)二、在 TypeScript 项目中使用流行的 JavaScript 库(如 jQuery、…

从源码构建安装Landoop kafka-connect-ui

背景 部署Landoop kafka-connect-ui最简单的办法还是通过docker来部署&#xff0c;我们之前的kafka-connect-ui就是通过docker部署的&#xff0c;但是&#xff0c;最近发现个问题&#xff1a;当使用docker部署且防火墙使用的是firewalld的情况下&#xff0c;就会出现端口冲突。…