【问题标题】:Write to File without Encoding写入文件而不编码
【发布时间】:2014-11-24 16:57:32
【问题描述】:

我从带有编码字符的 web 服务获取 JSON:\u201c 等。当我解析它时,它工作得很好:文本内的双引号具有编码字符值,而控制双引号没有编码,所以解析器看到正确的 JSON 结构。问题是在我将它写入文件并读取它之后,它会破坏 JSON。内容文本中不再有 \u201c,而是 " 字符。

  • 如果我使用 utf-8 对其进行编码," 将更改为文件分隔符 (28) 字符,- 将更改为控制设备 3 (0x13) 并导致解析异常。
  • 如果我使用 ascii 对其进行编码," 将更改为 ? 字符。
  • 如果我使用 iso-8859-1 对其进行编码," 将保持解码 "

有什么办法可以保存读写后未编码的字符?

示例:

我正在使用 Newtonsoft.Json.Linq

Encoding encoding = Encoding.GetEncoding("ISO-8859-1");
webResponse = (HttpWebResponse)webRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream(), encoding))
{
    responseString = streamReader.ReadToEnd();
}
JToken json = JObject.Parse(responseString);
using (StreamWriter stream = new StreamWriter(path, true, encoding))
{
    stream.Write(json.ToString());
}
string spoiledJsonString = File.ReadAllText(path, encoding);
JToken sureNotToBeCreated = JObject.Parse(spoiledJsonString); // EXCEPTION

【问题讨论】:

  • 如果您能展示一个简短但完整的程序来演示问题,那将非常有帮助。目前尚不清楚您是如何诊断的……您应该使用 UTF-8。
  • 写入是一回事,文件的读取和显示也很重要,我们没有任何相关信息。
  • 如果您想知道任何其他信息,请告诉我。
  • 如果之后不将输出视为 unicode,则不能使用 json.ToString()。要么使用正确的 unicode 编码,如 UTF-8(json 标准将 json 定义为 unicode 代码点序列),要么告诉你的 json 序列化器转义任何非 ASCII 字符。

标签: c# json web-services encoding streamwriter


【解决方案1】:

如果我写测试程序,

using System;
using System.Diagnostics;
using System.IO;
using System.Text;

class Program
{
    private static void Main()
    {
        var encoding = Encoding.GetEncoding("ISO-8859-1");
        var testString = new string(new[] { (char)0x201c });
        string roundTripped;

        using (var m = new MemoryStream())
        {
            using(var writer = new StreamWriter(m, encoding))
            {
                var reader = new StreamReader(m, encoding);
                writer.Write(testString);
                writer.Flush();
                m.Seek(0, SeekOrigin.Begin);
                roundTripped = reader.ReadToEnd();
            }
        }
    }

    Debug.Assert(
        string.Equals(testString, roundTripped),
        "These strings should be equal.");
}

我重新创建了您的问题,引用已被转义。

如果我将编码更改为Encoding.UTF8,它可以成功。


由于supported here,ISO-8859-1 不是 Unicode 字符集,因此对 Unicode 进行编码是一个糟糕的选择。

作为supported here,JSON 文本是 Unicode。

因此我们可以推断,ISO-8859-1 是编码 JSON 字符串的错误选择。


程序,

using System;
using System.Diagnostics;
using System.IO;
using System.Text;

using Newtonsoft.Json.Linq;

class Program
{
    private static void Main()
    {
        var encoding = Encoding.UTF8;
        var testJson = new JObject
            {
                new JProperty(
                    "AQuote",
                    string(new[] { (char)0x201c }))
            };

        JObject roundTripped;

        using (var m = new MemoryStream())
        {
            using(var writer = new StreamWriter(m, encoding))
            {
                var reader = new StreamReader(m, encoding);
                writer.Write(testJson.ToString());
                writer.Flush();
                m.Seek(0, SeekOrigin.Begin);
                roundTripped = JObject.Parse(reader.ReadToEnd());
            }
        }
    }

    Debug.Assert(
        string.Equals(
            testJson["AQuote"].Value<string>(),
            roundTripped["AQuote"].Value<string>()),
        "These strings should be equal.");
}

在没有警告的情况下运行,所以我怀疑除了 UTF-8 之外还有其他问题。

【讨论】:

  • 它现在正在保存,使用 ISO,并读取相同的 json!谢谢!
  • 问题是JToken生成的字符串被改变了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多