使用 System.Text.Json 即时格式化 JSON 流

2024-05-18

我有一个未缩进的 Json 字符串,例如:

{"hash":"123","id":456}

我想缩进字符串并将其序列化为 JSON 文件。天真地,我可以使用缩进字符串Newtonsoft如下。

using Newtonsoft.Json.Linq;

JToken token = JToken.Parse(json);
var formattedJson = JObject.Parse(token.ToString()).ToString();

但是,由于我使用了大量的大型 JSON 对象,因此我主要对可以对数据流进行操作的解决方案感兴趣。出于性能原因,我决定使用System.Text.Json,我想知道它是否具有任何用于处理数据流的开箱即用功能。

在推出我自己的解决方案之前,我想知道是否有任何方法具有大多数开箱即用的功能,理想情况下在将输入流写入存储时拦截输入流(即即时转换)。或者,我可以处理序列化流,但这需要读取文件,进行必要的更改,然后写入输出文件,而不需要首先将整个 JSON 反序列化到内存中。我主要对第一种方法感兴趣,因为 (a) 我将浏览一次 JSON,并且 (b) 不需要存储中间文件(流 -> 未格式化的 JSON -> 格式化的 JSON)。

动机

上游服务正在以 JSON 格式传输大量信息。下游服务逐行读取 JSON 并提取所需字段;大概是由于 JSON 文件太大,导致它们在内存中反序列化不切实际/不可行。但是,流式 JSON 需要遵循一些约定,以使其与下游服务兼容。所需的约定之一是缩进和每行一个键值对。上游服务似乎正在放弃所有格式以传输更少的位,但下游依赖于格式来提取信息。上游和下游服务都超出我的控制范围。我正在编写的服务的目标是坐在中间并对流式 JSON 进行必要的约定(缩进等格式就是其中之一),以使其与下游服务兼容。

如上所述,将流式 JSON 反序列化为对象,进行必要的更改,并将更新后的 JSON 序列化到磁盘,这似乎是一个显而易见的解决方案,但是,考虑到数据的大小和数量,这种方法对于我的应用程序来说是不切实际/不可行的。

我可以想到一个中间层,它可以动态处理流式 JSON,并在将这些位写入持久介质之前进行更改。然而,在走这条路之前,我想仔细检查一下是否有任何开箱即用的功能System.Text.Json来处理信息流。

Update

为了清晰起见并强调要点,该问题已进行了大幅更新:是否有任何开箱即用的功能System.Text.Json用于处理 JSON 流?


似乎没有简单的方法可以做到这一点System.Text.Json因为你不能使用Stream对象与System.Text.Json.Utf8JsonReader直接地。要绕过此限制,您需要使用以下命令将文件内容放入内存中System.Text.Json.JsonDocument对象如此明显,会占用大量内存。

目前,根据网上的信息,唯一的解决方案是记忆效率高是使用Newtonsoft.Json图书馆。

using (var streamReader = new StreamReader(sourceFilePath))
using (var jsonTextReader = new JsonTextReader(streamReader))
using (var streamWriter = File.CreateText(destinationFilePath))
using (var jsonTextWriter = new JsonTextWriter(streamWriter))
{
    jsonTextWriter.Formatting = Formatting.Indented;

    while (jsonTextReader.Read())
    {
        jsonTextWriter.WriteToken(jsonTextReader);
    }
}

使用 1MB 缓冲区而不是默认的 4kB,速度要快得多。 在 5 分 5 秒内将 6.33 GB 的文件缩进至 13.7 GB,总共约 200,000,000 行。它在 HDD 上读写,在 Visual Studio(调试版本)中运行,仅使用 17MB RAM。由于空间限制,无法在 SSD 上进行测试。

string filename = @"VeryBig.json";
using FileStream inputFileStream = new(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 1 * 1024 * 1024);
using StreamReader streamReader = new(inputFileStream);
using JsonTextReader jsonTextReader = new(streamReader);

string filenameOutput = Path.ChangeExtension(filename, ".indented.json");
using FileStream outputFileStream = new(filenameOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1 * 1024 * 1024);
using StreamWriter streamWriter = new(outputFileStream);
using JsonTextWriter jsonTextWriter = new(streamWriter);

jsonTextWriter.Formatting = Formatting.Indented;

while (jsonTextReader.Read())
{
    jsonTextWriter.WriteToken(jsonTextReader);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 System.Text.Json 即时格式化 JSON 流 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • C++:无法使用scoped_allocator_adaptor传播polymorphic_allocator

    我有一个vector
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 为什么禁止在 constexpr 函数中使用 goto?

    C 14 对你能做什么和不能做什么有规则constexpr功能 其中一些 没有asm 没有静态变量 看起来相当合理 但标准也不允许goto in constexpr功能 即使它允许其他控制流机制 这种区别背后的原因是什么 我以为我们已经过去
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐

  • 如何使整个跨度落入新行?

    这个片段显示了我想要的 http jsfiddle net 945Df 3 http jsfiddle net 945Df 3 div class sup strong a href Rosario Santa Fe Argentina a
  • IntelliJ 和 Maven - 找不到 mvn 命令

    我正在尝试构建一个使用 IntelliJ 创建的放置向导项目 当我跑步时 mvn package I get bash mvn command not found 我使用的是 Mac 并且正在遵循本教程 http www dropwizar
  • 警告消息 - 来自 dummies 包的 dummy

    我正在使用 dummies 包为分类变量生成虚拟变量 其中一些变量具有两个以上类别 testdf lt data frame A as factor c 1 2 2 3 3 1 B c A B A B C C C c D D E D D E
  • 呃!尝试将包发布到 npm 时出现 403

    我正在尝试将包发布到 npm 您可以在此处查看存储库 https github com biowaffeln mdx state https github com biowaffeln mdx state 我登录到 npmnpm login
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • 如何使 QImage 或 QPixmap 半透明 - 或者为什么 setAlphaChannel 过时?

    4 7 并喜欢在 qgraphicsview 上叠加两个图像 顶部的图像应是半透明的 以便能够透过它看到 最初 两个图像都是完全不透明的 我期望存在一些为每个像素设置全局 alpha 值的函数 但似乎没有这样的函数 最接近的是 QPixma
  • Spring-Data-JPA 参数化 NativeQuery 参数错误?

    我在 spring boot v1 5 1 应用程序中有这个 JPA 实体 Entity Table name score public class Score implements Serializable Id GeneratedVal
  • 剪切评级栏中的图像

    我制作了自己的评级栏 花朵图像有 4 种尺寸 xdpi hdpi 等 从 24px24px 到 64x64px
  • Hibernate HQL:将对值作为 IN 子句中的参数传递

    我面临一个问题 如何使用 IN 子句将查询中的成对值的参数传递给 HQL 例如 select id name from ABC where id reg date in x y 并且参数是不同的数据类型string id 和reg date
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 合并 url 中的 2 个输入值

    我有这样的形式
  • 适用于移动设备的响应式订单确认电子邮件?

    我从未见过令人惊叹的订单确认 发票电子邮件 即使是最好的 html5 网站也会发送糟糕的订单确认电子邮件 有时是纯文本 我相信这是因为发票通常需要使用表格来显示购买的物品 这在移动设备上实现起来非常困难 我发现了一些让手机上的表格更易于管理
  • pip 列出活动 virtualenv 中的全局包

    将 pip 从 1 4 x 升级到 1 5 后pip freeze输出我的全局安装 系统 软件包的列表 而不是我的 virtualenv 中安装的软件包的列表 我尝试再次降级到 1 4 但这并不能解决我的问题 这有点类似于这个问题 http
  • 如何删除标题中的粗体?

    我有一个标题 h1 THIS IS A HEADLINE h1 如何使短语 THIS IS 不加粗 其余部分不做任何更改 我在文本装饰中找不到任何相关标签 标题看起来很粗体 因为它大尺寸 如果您已应用粗体或想要更改行为 您可以执行以下操作
  • 将特定字形与网络字体一起使用

    使用网络字体 我想使用字体功能设置 CSS 中的选项以及跨度类HTML 中 以便使用字体集中的特定替代字形 我需要以正确的语法使用哪些值 GID Unicode 才能定位特定的目标glyph内glyph备择方案 这些功能使用 OpenTyp
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • 包含 contains 的 json 格式查询

    我在 ansible 中有以下 json 输出 active transaction null cores 4 hostname alpha auth wb01 active transaction null cores 4 hostnam
  • JavaFX - 为什么多次将节点添加到窗格或不同的窗格会导致错误?

    我现在正在学习基本的 JavaFX 我不明白我正在阅读的书中的这一说法 不 诸如文本字段之类的节点只能添加到一个窗格中一次 将节点添加到多次窗格或不同的窗格将导致运行时错误 我可以从书中提供的UML图看出它是一个组合 但我不明白为什么 库类
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken