首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JToken.WriteToAsync没有正确写入流

JToken.WriteToAsync没有正确写入流
EN

Stack Overflow用户
提问于 2021-05-11 12:06:54
回答 1查看 146关注 0票数 1

我想异步地将一个JToken写入流。我提到了JToken.WriteToAsync不写入JsonWriter。但是,流输出是?[],而ToString()输出是[]。为什么流在开头包含额外的字节?

我的代码如下:

代码语言:javascript
复制
static async Task Main(string[] args)
{
    JArray arr = new JArray();

    //var c = JToken.FromObject("abc");
    //arr.Add(c);

    var stream = new MemoryStream();

    await using (var requestWriter = new StreamWriter(stream, System.Text.Encoding.UTF8, leaveOpen: true))
    {
        var jsonWriter = new JsonTextWriter(requestWriter); 
        try
        {
            await arr.WriteToAsync(jsonWriter);
        }
        finally
        {
            await jsonWriter.CloseAsync();
        }
        Console.WriteLine(System.Text.Encoding.UTF8.GetString(stream.GetBuffer(), 0, checked((int)stream.Length)));

        Console.WriteLine(arr.ToString());

    }
}

为什么流输出不正确?The的版本为13.0.1。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-11 14:34:09

摘要

您的问题与异步写入无关。你的问题是Encoding.UTF8

返回提供Unicode字节顺序标记(BOM)的UTF8Encoding对象。

你看到的额外的?是BOM。为了防止BOM被写入,在编写时使用new UTF8Encoding(false)。或者,您可以只做new StreamWriter(stream, leaveOpen: true),因为默认情况下,建设者将使用UTF-8编码,而不使用字节顺序标记(BOM)。

详细信息

您的问题可以更简单地再现如下:

代码语言:javascript
复制
JArray arr = new JArray();

var stream = new MemoryStream();

using (var requestWriter = new StreamWriter(stream, System.Text.Encoding.UTF8, leaveOpen: true))
using (var jsonWriter = new JsonTextWriter(requestWriter))
{
    arr.WriteTo(jsonWriter);
}

var resultJson = Encoding.UTF8.GetString(stream.GetBuffer(), 0, checked((int)stream.Length));
Console.WriteLine(BitConverter.ToString(stream.GetBuffer(), 0, checked((int)stream.Length)));
Console.WriteLine(resultJson);
Console.WriteLine(arr.ToString());

Assert.AreEqual(arr.ToString(), resultJson);

断言失败的消息如下:

代码语言:javascript
复制
NUnit.Framework.AssertionException:   Expected string length 2 but was 3. Strings differ at index 0.

使用BitConverter.ToString()的以下输出

EF-BB-BF-5B-5D

演示小提琴这里

5B-5D是括号,但是EF-BB-BF的三个前导字符是什么?快速搜索显示它是8字节顺序标记。由于RFC 8259指定实现不能向网络传输的JSON文本的开头添加字节顺序标记(U+FEFF),所以应该使用new UTF8Encoding(false)省略BOM。因此,您的代码应该如下所示:

代码语言:javascript
复制
JArray arr = new JArray();

var stream = new MemoryStream();

await using (var requestWriter = new StreamWriter(stream, new UTF8Encoding(false), leaveOpen: true))
{
    var jsonWriter = new JsonTextWriter(requestWriter); 
    try
    {
        await arr.WriteToAsync(jsonWriter);
    }
    finally
    {
        await jsonWriter.CloseAsync();
    }
}

var resultJson = Encoding.UTF8.GetString(stream.GetBuffer(), 0, checked((int)stream.Length));
Console.WriteLine(BitConverter.ToString(stream.GetBuffer(), 0, checked((int)stream.Length)));
Console.WriteLine(resultJson);
Console.WriteLine(arr.ToString());

Assert.AreEqual(arr.ToString(), resultJson);

演示小提琴#2 这里

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67486440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档