【发布时间】:2019-05-22 15:35:21
【问题描述】:
我正在尝试将一个巨大的 JSON 文件 (2GB) 转换为 xml 文件。我在阅读巨大的 JSON 文件时遇到了一些麻烦。
我一直在研究如何读取巨大的 JSON 文件。
我发现了这个:
Out of memory exception while loading large json file from disk
How to parse huge JSON file as stream in Json.NET?
Parsing large json file in .NET
我似乎在重复我的问题,但我有一些问题在这些帖子中没有解决。
所以,我需要加载巨大的 JSON 文件,社区提出这样的建议:
MyObject o;
using (StreamReader sr = new StreamReader("foo.json"))
using (JsonTextReader reader = new JsonTextReader(sr))
{
var serializer = new JsonSerializer();
reader.SupportMultipleContent = true;
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
// Deserialize each object from the stream individually and process it
var o = serializer.Deserialize<MyObject>(reader);
//Do something with the object
}
}
}
所以,我们可以逐个读取,逐个反序列化对象。
我会告诉你我的代码
JsonSerializer serializer = new JsonSerializer();
string hugeJson = "hugJSON.json";
using (FileStream s = File.Open(hugeJson , FileMode.Open))
{
using (StreamReader sr = new StreamReader(s))
{
using (JsonReader reader = new JsonTextReader(sr))
{
reader.SupportMultipleContent = true;
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
var jsonObject = serializer.Deserialize(reader);
string xmlString = "";
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonObject.ToString(), "json");
using (var stringWriter = new StringWriter())
{
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
{
doc.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
xmlString = stringWriter.GetStringBuilder().ToString();
}
}
}
}
}
}
}
但是当我尝试doc.WriteTo(xmlTextWriter) 时,我得到Exception of type System.OutOfMemoryException was thrown.
我一直在尝试使用BufferedStream。这个类允许我管理大文件,但我还有另一个问题。
我正在阅读byte[] 格式。当我转换为字符串时,json 被拆分,我无法解析为 xml 文件,因为缺少字符
例如:
{ foo:[{
foo:something,
foo1:something,
foo2:something
},
{
foo:something,
foo:som
它被剪掉了。
有什么方法可以读取巨大的 JSON 并将其转换为 XML 而无需按部分加载 JSON?或者我可以按部分加载转换,但我不知道该怎么做。
有什么想法吗?
更新:
我一直在尝试使用此代码:
static void Main(string[] args)
{
string json = "";
string pathJson = "foo.json";
//Read file
string temp = "";
using (FileStream fs = new FileStream(pathJson, FileMode.Open))
{
using (BufferedStream bf = new BufferedStream(fs))
{
byte[] array = new byte[70000];
while (bf.Read(array, 0, 70000) != 0)
{
json = Encoding.UTF8.GetString(array);
temp = String.Concat(temp, json);
}
}
}
XmlDocument doc = new XmlDocument();
doc = JsonConvert.DeserializeXmlNode(temp, "json");
using (var stringWriter = new StringWriter())
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
{
doc.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
xmlString = stringWriter.GetStringBuilder().ToString();
}
File.WriteAllText("outputPath", xmlString);
}
此代码从 json 文件转换为 xml 文件。但是当我尝试转换一个大的 json 文件(2GB)时,我不能。该过程花费大量时间,并且字符串没有存储所有 json 的能力。我怎样才能存储它?有什么方法可以在不使用数据类型字符串的情况下进行这种转换?
更新: json格式为:
[{
'key':[some things],
'data': [some things],
'data1':[A LOT OF ENTRIES],
'data2':[A LOT OF ENTRIES],
'data3':[some things],
'data4':[some things]
}]
【问题讨论】:
-
尽量避免内存 I/O,例如
StringWriter,并将所有块输出到文件流。您可以继续附加到该文件流,而无需为每个块添加一个新文件。如果您可以完全避免反序列化,而是读取令牌和输出元素,这也会有很大帮助 -
1)
xmlString生成后要做什么?您已经拥有XmlDocument doc表示,为什么还需要xmlString? 2) 能否请edit 分享一个 JSON 样本? -
@dbc
xmlString在这段代码中毫无价值。 2) 为什么需要 JSON 样本?我不能使用数据模型。程序必须读取任何大的 JSON。 -
@StenPetrov 有什么方法可以在不使用数据类型字符串的情况下进行转换?
-
例如,您可能会遇到XmlNodeConverter can only convert JSON that begins with an object 中描述的问题。