Last active
December 4, 2024 21:21
-
-
Save NickStrupat/0093d6b84ae2d784e6484123c7922fcf to your computer and use it in GitHub Desktop.
JSON serialization of a stream
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Buffers.Text; | |
using System.Text.Json; | |
using System.Text.Json.Serialization; | |
var text = "Hello, World! How are ya? Good! That's swell!"u8; | |
{ | |
using var ms = new MemoryStream(text.ToArray()); | |
var foo = new Foo("text", ms); | |
using var fs = File.Create("yes.txt", 4096, FileOptions.WriteThrough); | |
JsonSerializerOptions jso = new() { Converters = { new StreamToBase64WriteOnlyJsonConverter(fs) }}; | |
using var writer = new Utf8JsonWriter(fs); | |
JsonSerializer.Serialize(writer, foo, jso); | |
} | |
var json = File.ReadAllText("yes.txt"); | |
Console.WriteLine(json); | |
Console.WriteLine(Convert.ToBase64String(text)); | |
record Foo(string Name, Stream Reader); | |
public sealed class StreamToBase64WriteOnlyJsonConverter(Stream writeStream) : JsonConverter<Stream> | |
{ | |
public override Stream Read(ref Utf8JsonReader r, Type ttc, JsonSerializerOptions o) => throw new NotImplementedException(); | |
public override void Write(Utf8JsonWriter writer, Stream value, JsonSerializerOptions options) | |
{ | |
writer.WriteNumberValue(0); // write a dummy value so the writer knows it has written a value | |
writer.Flush(); // flush the writer to the underlying stream | |
writeStream.Position -= 1; // move the stream back one byte to overwrite the dummy value | |
writeStream.Write("\""u8); | |
Span<byte> buffer = stackalloc byte[4]; | |
var maxNonBase64Bytes = Base64.GetMaxDecodedFromUtf8Length(buffer.Length); | |
int read; | |
while ((read = value.Read(buffer[..maxNonBase64Bytes])) != 0) | |
{ | |
Base64.EncodeToUtf8InPlace(buffer, read, out var bytesWritten); | |
writeStream.Write(buffer[..bytesWritten]); | |
} | |
writeStream.Write("\""u8); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment