Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Newtonsoft ToObject反序列化许多Json文件_C#_.net_Json_Json.net - Fatal编程技术网

C# 使用Newtonsoft ToObject反序列化许多Json文件

C# 使用Newtonsoft ToObject反序列化许多Json文件,c#,.net,json,json.net,C#,.net,Json,Json.net,这里有效率很低的东西吗?这一过程似乎比应该的时间要长。我正在解析许多JSON文件,每个文件都有一个JsonArray对象。也许有经验的人可以指出这种将JSON解析为对象的方法中的一个错误,从而为我节省大量时间 此外,内存使用缓慢地一个接一个地增加,有时会导致OutOfMemory异常 public void Parse(){ using (BabysFirstsUsersDataEntities db = new BabysFirstsUsersDataEntities() {

这里有效率很低的东西吗?这一过程似乎比应该的时间要长。我正在解析许多JSON文件,每个文件都有一个JsonArray对象。也许有经验的人可以指出这种将JSON解析为对象的方法中的一个错误,从而为我节省大量时间

此外,内存使用缓慢地一个接一个地增加,有时会导致OutOfMemory异常

public void Parse(){

    using (BabysFirstsUsersDataEntities db = new BabysFirstsUsersDataEntities()
    {

           foreach (var path in Directory.EnumerateFiles(@"C:\\examplepath\").OrderBy(f => f))
           {
                    string jsonString = System.IO.File.ReadAllText(path);
                    JToken tok = JObject.Parse(jsonString);
                    Debug.WriteLine("path: " + path);

                    foreach (var x in tok.First.First)
                    {

                            JsonUserImageDTO jdto = x.ToObject<JsonUserImageDTO>();
                            UserImageList uil = jdto.ToDataModel();

                            if (uil.REID != null)
                                db.UserImageLists.Add(uil);    

                    }
            }
      db.SaveChanges();              
    }
}

您可以创建对象,然后反序列化它们。 例如:

JsonConvert.DeserializeObject<RootObject>(jsonString);

public class Asdf
{
    public bool read { get; set; }
    public bool write { get; set; }
}

public class RoleAdmin
{
    public bool read { get; set; }
}

public class ACL
{
    public Asdf asdf { get; set; }
    public RoleAdmin { get; set; }
}

public class Result
{
    public ACL ACL { get; set; }
    public string REID { get; set; }
    public string createdAt { get; set; }
    public string email { get; set; }
    public string objectId { get; set; }
    public string updatedAt { get; set; }
    public int urlCount { get; set; }
    public List<string> urlList { get; set; }
}

public class RootObject
{
    public List<Result> results { get; set; }
}
JsonConvert.DeserializeObject(jsonString);
公共类Asdf
{
公共bool read{get;set;}
公共bool write{get;set;}
}
公共类RoleAdmin
{
公共bool read{get;set;}
}
公共类ACL
{
公共Asdf Asdf{get;set;}
public RoleAdmin{get;set;}
}
公开课成绩
{
公共ACL ACL{get;set;}
公共字符串REID{get;set;}
公共字符串createdAt{get;set;}
公共字符串电子邮件{get;set;}
公共字符串objectId{get;set;}
公共字符串updatedAt{get;set;}
public int urlCount{get;set;}
公共列表urlList{get;set;}
}
公共类根对象
{
公共列表结果{get;set;}
}

您可以创建对象,然后反序列化它们。 例如:

JsonConvert.DeserializeObject<RootObject>(jsonString);

public class Asdf
{
    public bool read { get; set; }
    public bool write { get; set; }
}

public class RoleAdmin
{
    public bool read { get; set; }
}

public class ACL
{
    public Asdf asdf { get; set; }
    public RoleAdmin { get; set; }
}

public class Result
{
    public ACL ACL { get; set; }
    public string REID { get; set; }
    public string createdAt { get; set; }
    public string email { get; set; }
    public string objectId { get; set; }
    public string updatedAt { get; set; }
    public int urlCount { get; set; }
    public List<string> urlList { get; set; }
}

public class RootObject
{
    public List<Result> results { get; set; }
}
JsonConvert.DeserializeObject(jsonString);
公共类Asdf
{
公共bool read{get;set;}
公共bool write{get;set;}
}
公共类RoleAdmin
{
公共bool read{get;set;}
}
公共类ACL
{
公共Asdf Asdf{get;set;}
public RoleAdmin{get;set;}
}
公开课成绩
{
公共ACL ACL{get;set;}
公共字符串REID{get;set;}
公共字符串createdAt{get;set;}
公共字符串电子邮件{get;set;}
公共字符串objectId{get;set;}
公共字符串updatedAt{get;set;}
public int urlCount{get;set;}
公共列表urlList{get;set;}
}
公共类根对象
{
公共列表结果{get;set;}
}

看起来可能有几个地方会导致速度缓慢

  • 反序列化JSON
  • 将对象转换两次(
    jdto
    ,然后
    uil
  • 保存到数据库
  • 可能需要对代码进行分析,以确定哪个部分所花的时间比您预期的要长。也就是说,您可以做一些事情来改进这段代码

  • 从蒸汽而不是字符串反序列化。按照您的方式,基本上在内存中有两次对象——一次作为字符串,然后一次作为
    tok
    。有关如何使用流,请参见第二个示例。实际上,在您的例子中,您在内存中保存了4次相同的信息——字符串、
    tok
    jdto
    uil
    。这就引出了下一点
  • 尝试消除对象的一些中间表示。通常,放置的对象越多,等待GC的时间就越长
  • 将路径名上的筛选移动到调用
    EnumerateFiles()
    的部分。如果您不打算对文件执行任何操作,那么反序列化文件是没有意义的

  • 看起来可能有几个地方会导致速度变慢

  • 反序列化JSON
  • 将对象转换两次(
    jdto
    ,然后
    uil
  • 保存到数据库
  • 可能需要对代码进行分析,以确定哪个部分所花的时间比您预期的要长。也就是说,您可以做一些事情来改进这段代码

  • 从蒸汽而不是字符串反序列化。按照您的方式,基本上在内存中有两次对象——一次作为字符串,然后一次作为
    tok
    。有关如何使用流,请参见第二个示例。实际上,在您的例子中,您在内存中保存了4次相同的信息——字符串、
    tok
    jdto
    uil
    。这就引出了下一点
  • 尝试消除对象的一些中间表示。通常,放置的对象越多,等待GC的时间就越长
  • 将路径名上的筛选移动到调用
    EnumerateFiles()
    的部分。如果您不打算对文件执行任何操作,那么反序列化文件是没有意义的

  • 你真的分析过你的代码吗?请参阅Erik Lippert的:在开始调查备选方案之前,使用探查器或其他分析工具以经验方式确定瓶颈在哪里。例如,您的实际性能问题可能在
    BabysFirstsUsersDataEntities db
    类中的某个地方

    话虽如此,我的直接反应是,数据的中间表示太多了,构建、人口和垃圾收集都需要时间。这些措施包括:

    • jsonString
      可能足够大,可以继续运行,从而永久性地影响进程的性能和内存使用
    • 整个JSON层次结构的
      JToken-tok
      表示
    • 每个人
      JsonUserImageDTO
    我的建议是尽可能多地消除这些中间表示。正如中所建议的,您应该直接从流加载,而不是加载到字符串并解析该字符串

    您还可以通过直接填充数据模型来消除jtokentok。假设您的
    BabyFirstSusersDataEntities
    看起来像这样(我只是在这里猜测):


    通过填充预先分配的
    rootDTO
    ConvertingCollection
    ,您的
    db.userImageList
    将被JSON的内容填充,中间表示形式更少。

    您实际分析过代码吗?请参阅Erik Lippert的:使用剖析器或其他分析工具来确定经验数据
    public class BabysFirstsUsersDataEntities
    {
        public BabysFirstsUsersDataEntities() { this.UserImageLists = new List<UserImageList>(); }
    
        public List<UserImageList> UserImageLists { get; set; }
    }
    
    public class UserImageList
    {
        public string email { get; set; }
        public List<string> urlList;
    }
    
    public class RootObjectDTO
    {
        public ICollection<JsonUserImageDTO> results { get; set; }
    }
    
    public class JsonUserImageDTO
    {
        public ACL ACL { get; set; }
        public string REID { get; set; }
        public string createdAt { get; set; }
        public string email { get; set; }
        public string objectId { get; set; }
        public string updatedAt { get; set; }
        public int urlCount { get; set; }
        public List<string> urlList { get; set; }
    
        public UserImageList ToDataModel()
        {
            return new UserImageList { email = email, urlList = urlList };
        }
    }
    
    public class Asdf
    {
        public bool read { get; set; }
        public bool write { get; set; }
    }
    
    public class RoleAdmin
    {
        public bool read { get; set; }
    }
    
    public class ACL
    {
        public Asdf asdf { get; set; }
    
        [JsonProperty("role:admin")]
        public RoleAdmin RoleAdmin { get; set; }
    }
    
    public class ConvertingCollection<TIn, TOut> : BaseConvertingCollection<TIn, TOut, ICollection<TIn>>
    {
        readonly Func<TOut, TIn> toInner;
    
        public ConvertingCollection(Func<ICollection<TIn>> getCollection, Func<TIn, TOut> toOuter, Func<TOut, TIn> toInner)
            : base(getCollection, toOuter)
        {
            if (toInner == null)
                throw new ArgumentNullException();
            this.toInner = toInner;
        }
    
        protected TIn ToInner(TOut outer) { return toInner(outer); }
    
        public override void Add(TOut item)
        {
            Collection.Add(ToInner(item));
        }
    
        public override void Clear()
        {
            Collection.Clear();
        }
    
        public override bool IsReadOnly { get { return Collection.IsReadOnly; } }
    
        public override bool Remove(TOut item)
        {
            return Collection.Remove(ToInner(item));
        }
    
        public override bool Contains(TOut item)
        {
            return Collection.Contains(ToInner(item));
        }
    }
    
    public abstract class BaseConvertingCollection<TIn, TOut, TCollection> : ICollection<TOut>
    where TCollection : ICollection<TIn>
    {
        readonly Func<TCollection> getCollection;
        readonly Func<TIn, TOut> toOuter;
    
        public BaseConvertingCollection(Func<TCollection> getCollection, Func<TIn, TOut> toOuter)
        {
            if (getCollection == null || toOuter == null)
                throw new ArgumentNullException();
            this.getCollection = getCollection;
            this.toOuter = toOuter;
        }
    
        protected TCollection Collection { get { return getCollection(); } }
    
        protected TOut ToOuter(TIn inner) { return toOuter(inner); }
    
        #region ICollection<TOut> Members
    
        public abstract void Add(TOut item);
    
        public abstract void Clear();
    
        public virtual bool Contains(TOut item)
        {
            var comparer = EqualityComparer<TOut>.Default;
            foreach (var member in Collection)
                if (comparer.Equals(item, ToOuter(member)))
                    return true;
            return false;
        }
    
        public void CopyTo(TOut[] array, int arrayIndex)
        {
            foreach (var item in this)
                array[arrayIndex++] = item;
        }
    
        public int Count { get { return Collection.Count; } }
    
        public abstract bool IsReadOnly { get; }
    
        public abstract bool Remove(TOut item);
    
        #endregion
    
        #region IEnumerable<TOut> Members
    
        public IEnumerator<TOut> GetEnumerator()
        {
            foreach (var item in Collection)
                yield return ToOuter(item);
        }
    
        #endregion
    
        #region IEnumerable Members
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    
        #endregion
    }
    
            var rootDTO = new RootObjectDTO
            {
                results = new ConvertingCollection<UserImageList, JsonUserImageDTO>(() => db.UserImageLists, (x) => { throw new NotImplementedException(); }, (x) => x.ToDataModel())
            };
    
            using (var stream = File.Open(path, FileMode.Open))
            using (var reader = new StreamReader(stream))
            {
                JsonSerializer.CreateDefault().Populate(reader, rootDTO);
            }