You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#将JSON转换为对象并读取大JSON文件?

解决多层JSON转C#对象失败及大文件高效读取问题

嘿,我来帮你搞定这两个问题——先是你的JSON转C#对象失败的问题,再聊聊大文件读取的最佳实践~

一、修复C#类的映射问题

你当前的代码里手动用反射+JObject构造函数来取值,这不仅麻烦,还容易出错(比如你在Property类里错误地重复拿了type属性,而不是R_STATEFP和L_STATEFP)。其实Newtonsoft.Json(Json.NET)完全可以自动完成多层JSON到C#类的映射,根本不需要手动写这些构造函数。

重构后的C#类

直接用简洁的属性定义即可,Json.NET会自动匹配JSON字段名(注意大小写要对应,JSON里的字段名和类的属性名大小写一致就行):

using System.Collections.Generic;
using Newtonsoft.Json;

namespace MyApp
{
    public class FeatureCollection
    {
        public string type { get; set; }
        public List<Feature> features { get; set; }
    }

    public class Feature
    {
        public string type { get; set; }
        public Property properties { get; set; }
        public Geometry geometry { get; set; }
    }

    public class Property
    {
        public string TYPE { get; set; }
        public string R_STATEFP { get; set; }
        public string L_STATEFP { get; set; }
    }

    public class Geometry
    {
        public string type { get; set; }
        public List<Coord> coordinates { get; set; }
    }

    public class Coord
    {
        // 用构造函数让Json.NET自动把[经度,纬度]数组转成Coord对象
        [JsonConstructor]
        public Coord(double longitude, double latitude)
        {
            this.longitude = longitude;
            this.latitude = latitude;
        }

        public double longitude { get; set; }
        public double latitude { get; set; }
    }
}

为什么原来的代码会失败?

你之前用i.GetType().GetProperty("type")是错误的思路:JObject是动态JSON对象,它的.GetType()返回的是.NET的JObject类型,这个类型的属性和JSON里的字段完全无关。正确的取值方式应该是i["type"].Value<string>(),但其实完全没必要这么做——Json.NET的自动映射已经帮你搞定了所有多层嵌套的匹配。

测试反序列化

现在你可以用一行代码完成反序列化(如果文件不算特别大的话):

var featureCollection = JsonConvert.DeserializeObject<FeatureCollection>(File.ReadAllText("your-file.json"));

二、大文件读取的最佳方式

如果你的JSON文件包含几百上千个Feature,甚至更大,直接用File.ReadAllText会把整个文件加载到内存,可能导致内存占用过高。最优方案是用JsonTextReader做流式处理,逐个读取Feature并处理,而不是一次性加载整个FeatureCollection。

流式读取示例代码

using System.IO;
using Newtonsoft.Json;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var filePath = "your-large-file.json";
            
            // 流式读取,逐个处理Feature
            using (var streamReader = new StreamReader(filePath))
            using (var jsonReader = new JsonTextReader(streamReader))
            {
                var serializer = new JsonSerializer();
                
                // 定位到features数组的开始
                while (jsonReader.Read())
                {
                    if (jsonReader.TokenType == JsonToken.StartArray && jsonReader.Path == "features")
                        break;
                }
                
                // 逐个反序列化Feature
                while (jsonReader.Read())
                {
                    if (jsonReader.TokenType == JsonToken.EndArray)
                        break; // 数组读完了,退出循环
                    
                    if (jsonReader.TokenType == JsonToken.StartObject)
                    {
                        // 反序列化单个Feature
                        var feature = serializer.Deserialize<Feature>(jsonReader);
                        
                        // 在这里处理每个Feature,比如存入数据库、打印信息等
                        Console.WriteLine($"读取到Feature:TYPE={feature.properties.TYPE}, 坐标数量={feature.geometry.coordinates.Count}");
                    }
                }
            }
        }
    }
}

这种方式的优势是内存占用极低,因为每次只在内存中保留一个Feature对象,适合处理GB级别的大JSON文件。如果你的文件只是100+个Feature,其实直接反序列化整个FeatureCollection也没问题,但流式处理是更专业的大文件处理方案。

内容的提问来源于stack exchange,提问作者Amy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:25:29