大 JSON 文件

Large JSON file

我有很大的 json 文件,我需要使用 .NET 6 从 Web API return 它们。 应该添加一些元数据,所以 DTO 看起来像这样

public class Response
{
  public int Id { get; set; }
  public T Content { get; set; }
}

尝试使用 Utf8JsonWriter,但没有成功。它没有 api 来写入流。 有没有办法在不分配内存的情况下流式传输文件?

await using var writer = new Utf8JsonWriter(Response.Body, new JsonWriterOptions{SkipValidation = true});
writer.WriteStartObject();
writer.WriteNumber("Id", 1);
writer.WritePropertyName("Content");
writer.WriteRawValue(GetStream(filePath));  // there is a way to do this?

await writer.FlushAsync();

您可以将文件完全缓冲到 byte 数组中,然后使用 WriteRawValue

写入
await using var writer = new Utf8JsonWriter(Response.Body, new JsonWriterOptions{SkipValidation = true});
writer.WriteStartObject();
writer.WriteNumber("Id", 1);
writer.WritePropertyName("Content");

await using var file = GetStream(filePath);
var buffer = new byte[file.Length];
using (var memoryStream = new MemoryStream(buffer))
await file.CopyToAsync(memoryStream);
writer.WriteRawValue(buffer, true);
writer.WriteEndObject();
await writer.FlushAsync();

或者您可以将其流式传输。您不能为此使用 WriteRawValue,因为它需要一个值。即使是SkipValidation,也会把writer的状态搞乱,所以需要直接把属性的名字和值写到底层流中。

await using var writer = new Utf8JsonWriter(Response.Body, new JsonWriterOptions{SkipValidation = true});
writer.WriteStartObject();
writer.WriteNumber("Id", 1);
await writer.FlushAsync();  // you MUST flush the JSON writer first
await Response.Body.WriteAsync(Encoding.UTF8.GetBytes(@"""Content"":"));
var buffer = new byte[4096];
await using var file = GetStream(filePath);
await file.CopyToAsync(Response.Body);
writer.WriteEndObject();
await writer.FlushAsync();