C# 异步传输联机json信息
我正在尝试制作一个程序,使用数据来寻找大型3D数学网络的解决方案。在JSON格式中,有一个节点数组和有关其在3D空间中位置的信息,以及它们具有哪些属性等。您可以请求两种格式: 标准JSON数组:C# 异步传输联机json信息,c#,json,C#,Json,我正在尝试制作一个程序,使用数据来寻找大型3D数学网络的解决方案。在JSON格式中,有一个节点数组和有关其在3D空间中位置的信息,以及它们具有哪些属性等。您可以请求两种格式: 标准JSON数组:https://www.example.com/nodes.json [{"ID": 1, "Type": "Node", "x": 0, "y": 0, "z": 0}, {"
https://www.example.com/nodes.json
[{"ID": 1, "Type": "Node", "x": 0, "y": 0, "z": 0}, {"ID": 2, "Type": "OtherNode", "x": 1, "y": 0, "z": 0}, ...
行分隔数组:https://www.example.com/nodes.jsonl
{"ID": 1, "Type": "Node", "x": 0, "y": 0, "z": 0}
{"ID": 2, "Type": "OtherNode", "x": 1, "y": 0, "z": 0}
...
我的班级:
class Node
{
ulong ID { get; set; }
nodeType Type { get; set; }
decimal X { get; set; }
decimal Y { get; set; }
decimal Z { get; set; }
}
这些节点集合可能会变得非常大。GBs可能很大,但谢天谢地,每天只需要更新一次。问题是,如果我让它下载JSON异步,程序在整个下载之前仍然无法使用
WebClient.DownloadFile(settings.URL, path);
List<Node> nodes = JsonConvert.DeserializeObject<List<Node>>(path);
WebClient.DownloadFile(settings.URL,path);
List nodes=JsonConvert.DeserializeObject(路径);
但是,如果我有前几个节点,我仍然可以开始求解网络,而不需要整个节点集。如果我可以使用某种流一次下载一个字符的文件,我可以绕过它。使用行分隔格式,我可以执行以下操作:
SomeStream someStream = new SomeStream(URL);
while(!someStream.eof)
{
string jsonString = someStream.ReadLine();
nodes.Add(JsonConvert.DeserializeObject<Node>(jsonString));
}
SomeStream-SomeStream=新的SomeStream(URL);
而(!someStream.eof)
{
字符串jsonString=someStream.ReadLine();
Add(JsonConvert.DeserializeObject(jsonString));
}
我担心这可能不可能,除非网站支持一次一行地请求数据。如果其他方法解决了这个问题,我仍然愿意学习。据我所知,没有json解析器有一个IAsyncEnumerbale
反序列化程序
但是,只要您不处理流,我们就应该能够使用常规迭代器来实现这一点
public static IEnumerable<Node> ReadStream(Stream stream)
{
var serializer = new JsonSerializer();
using var reader = new StreamReader(stream);
using var jsonReader = new JsonTextReader(reader) {SupportMultipleContent = true};
while (jsonReader.Read())
yield return serializer.Deserialize<Node>(jsonReader);
}
注意:这是完全未经测试的,因为我没有一个url可以提供连续的json提要,而无需费劲地编写一个。必须向不可为null的类型添加?,以允许json中为null,除此之外,这也非常有效。
var httpclient = new HttpClient(); // dont do this, just an example
// note don't dispose the stream until its finished enumerating, or your will regret it
var stream = await httpclient.GetStreamAsync("https://www.example.com/nodes.json");
foreach (var item in ReadStream(stream))
Console.WriteLine(item.ID);