简体   繁体   English

如何在不使用 File.ReadAllLines 的情况下从 json 文件中读取序列化对象? C#

[英]How to read serialized objects from json file without use File.ReadAllLines? C#

In a lot of examples i have one object and File.ReadAllLines which can be simple deserialized (because this is one object, one string, and we needn't split it. But what can i do with collection of objects?在很多例子中,我有一个 object 和 File.ReadAllLines 可以简单地反序列化(因为这是一个 object,一个字符串,我们不需要拆分它。但是我可以用对象集合做什么?

I have a simple class customer and i would like to serialize list with this kind of objects.我有一个简单的 class 客户,我想用这种对象序列化列表。 For example例如

var customer = new Customer()
            {
                FirstName = "Luiggi",
                LastName = "Somf",
                Address = "3 Wall St"
            };

List<Customer> list = new List<Customer>();

And there, first question, is there any better way to easier serialize list of objects and write it to file?还有,第一个问题,有没有更好的方法来更容易地序列化对象列表并将其写入文件?

StreamWriter writer = new StreamWriter("file.json");

            foreach(Customer cust in list)
            {
                string json = JsonSerializer.Serialize(cust);
                writer.Write(json);
            }

            writer.Close();

And the second, is there easier way to read this collection or single objects from file than read line, split it (maybe using regex), deserialize, and next, add this to list?第二,有没有比读取行更容易从文件中读取这个集合或单个对象的方法,拆分它(可能使用正则表达式),反序列化,然后将它添加到列表中?

StreamReader reader = new StreamReader("file.json");

            string[] jsons;

            while (!reader.EndOfStream)
            {
                jsons = reader.ReadLine().Split('}');
                
            }
            reader.Close();

Thank you very much!非常感谢!

You can serialize the entire list.您可以序列化整个列表。 By simply serializing the list object.通过简单地序列化列表 object。

Just write:写吧:

JsonSerializer.Serialize(list); JsonSerializer.Serialize(list); Instead of:代替:

JsonSerializer.Serialize(cust); JsonSerializer.Serialize(cust);

And get rid of the for loop.并摆脱 for 循环。

There are a few ways to solve the problem, however I would recommend not serialising individual objects if you want to read/write an entire file at a time.有几种方法可以解决这个问题,但是如果你想一次读取/写入整个文件,我建议不要序列化单个对象。

In the simplest of ways, you can just serialise and deserialise the list, like so:以最简单的方式,您可以对列表进行序列化和反序列化,如下所示:

//Serialise and Save
await File.WriteAllTextAsync("file.json", JsonSerializer.Serialize(list));

//Deserialise
Customers customers = JsonSerializer.Deserialize<List<Customers>>(await File.ReadAllTextAsync("file.json"));

However, there are better, cleaner ways.但是,有更好、更清洁的方法。

Firstly I would recommend modelling the file separately:首先,我建议单独对文件进行建模:

public class CustomersFile
{
    public List<Customer> Customers {get; set; }
}
//....

....//
public CustomersFile customersFile = new();

then I would serialise and deserialise this.然后我会序列化和反序列化这个。

//Serialise and Save
await File.WriteAllTextAsync("file.json", JsonSerializer.Serialize(customersFile));

//Deserialise
CustomersFile customersFile = JsonSerializer.Deserialize<CustomersFile>(await File.ReadAllTextAsync("file.json"));

once I'd loaded the file into memory, it's simply a case of using linq to retrieve what you need.一旦我将文件加载到 memory 中,这只是使用 linq 来检索您需要的内容的情况。

//iterate through the list as normal
foreach(Customer customer in customersFile.Customers)
{
    Console.WriteLine(customer.LastName);
}

//Get the record by name/details
IEnumerable<Customer> foundCustomers = customersFile.Customers.Where(c => c.LastName.Equals("Somf"));

Now, this doesn't solve the "looking through a file to find the correct record", as it involved loading the file into memory and deserialising every time you want to find something, however a few questions:现在,这并不能解决“通过文件查找正确记录”的问题,因为它涉及将文件加载到 memory 并在每次您想查找某些内容时反序列化,但是有几个问题:

Why do you need to iterate through the file, not just through the collection?为什么需要遍历文件,而不仅仅是遍历集合?

Why are you using a flat file as storage?为什么使用平面文件作为存储?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM