C# 批量反序列化很多 json 个文件

C# Batch deserialization of a lot of json files

我在文件系统上有 200.000 json 个文件。

将它们一个接一个地反序列化并放入一个列表中大约需要 4 分钟。

我正在寻找反序列化它们的最快方法或同时反序列化它们的方法。

代码示例

我使用的代码是这样的:

var files = Directory.GetFiles(@"C:\Data","*.json");
        var list = new List<ParsedData>();
        var dt1 = DateTime.Now;
        foreach(var file in files)
        {
            using (StreamReader filestr = File.OpenText(file))
            {
                JsonSerializer serializer = new JsonSerializer();
                var  data= (ParsedData)serializer.Deserialize(filestr, typeof(ParsedData));
                list.Add(data);
            }
        }
        var dt2 = DateTime.Now;

        Console.WriteLine((dt2 - dt1).TotalMilliseconds);

JSON格式

而 json 样本是:

{

  "channel_name": "@channel",
  "message": "",
  "text": "",
  "date": "2015/10/09 12:22:48",
  "views": "83810",
  "forwards": "0",
  "raw_text": "",
  "keywords_marked": "",
  "id": 973,
  "media": "1.jpg"
}

您可以尝试使用 Parallel.Foreach():

            var files = Directory.GetFiles(@"C:\Data", "*.json");
            var list = new ConcurrentBag<ParsedData>();
            var dt1 = DateTime.Now;
            Parallel.ForEach(files, (file) =>
            {
                var filestr = File.ReadAllText(file);
                var data = JsonSerializer.Deserialize<ParsedData>(filestr);
                list.Add(data);
            });
            var dt2 = DateTime.Now;

            Console.WriteLine((dt2 - dt1).TotalMilliseconds);

编辑: 去掉var files = Directory.GetFiles(@"C:\Data", "*.json");然后直接试试:

            Parallel.ForEach(Directory.EnumerateFiles(@"C:\Data", "*.json"), (file) =>
            {
                var filestr = File.ReadAllText(file);
                var data = JsonSerializer.Deserialize<ParsedData>(filestr);
                list.Add(data);
            });

但是对于 200000 个文件,50 秒似乎已经下降了。

如果您使用.NET6,您可以使用:

Parallel.ForEachAsync( ... async(file) => {
  var fs = new FileStream(file, FileMode.Open);
  var data = await JsonSerializer.DeserializeAsync<ParsedData>(fs);
  list.Add(data);
});