使用 JSON 后关闭文件
Close a file after using it with JSON
我发现该函数可以正确地用于 JSON 解析:
var objs = JObject.Load(new JsonTextReader(new StreamReader(JsonPath)))
.SelectTokens("*")
.Select(t => JsonConvert.DeserializeObject<Cars>(t.ToString()));
但它在使用后不会释放文件(所以我不能将它用于其他功能)...我尝试使用函数 Close,但似乎无法处理该对象!
P.s。我已经检查了与该主题相关的 previous open-one question,但没有人谈论如何访问对象字段,而且如果我们计算我有超过 1 个对象,那么问题似乎有所不同......猜猜有人可以更好地解释它是如何工作的...
首先用using块读取文件并做JSON操作
最好将它放在一个单独的方法中,如下所示
private string readFile()
{
string buffer = null;
using (System.IO.FileStream stm = new
System.IO.FileStream("c:\YourFile.txt",System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.None))
{
using (System.IO.StreamReader rdr = new System.IO.StreamReader (stm))
{
buffer=rdr.ReadToEnd();
}
}
return buffer
}
private Object Deserialize(string content)
{
//do conversion here
}
来自 JSON.NET 网站 Read JSON from a File :
// read JSON directly from a file
using (StreamReader file = File.OpenText(@"c:\videogames.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
JObject o2 = (JObject)JToken.ReadFrom(reader);
}
问题的代码做了一些不必要的事情 - 它试图将已经反序列化的 JObject 序列化回 JSON,然后再次将其反序列化为 Car
。为什么不反序列化原始文件一次?
文档也在 Deserialize JSON from a file 中描述了这一点:
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(@"c:\movie.json"))
{
JsonSerializer serializer = new JsonSerializer();
Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
}
JSON 文档只能包含一个对象。如果文件内容如下所示:
{
"Movies":[{
"Title":"abc"
}, {
"Title":"abc"
}]
}
根对象应该包含一个 Movies
属性,其中包含一个 Movie[]
数组:
class RootObjedt
{
public Movie[] Movies{get;set;}
}
...
using (StreamReader file = File.OpenText(@"c:\movie.json"))
{
JsonSerializer serializer = new JsonSerializer();
var root = (Movie)serializer.Deserialize(file, typeof(RootObject));
var movies=root.Movies;
}
我建议您读取 json 数据异步,因为此方法具有将流作为输入的重载,因此您可以像这样在两个代码串中读取数据:
ProjFolder\Program.cs
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Whosebug.Models;
namespace Whosebug
{
class Program
{
static async Task Main(string[] args)
{
using var openStream = File.OpenRead(@"D:\Code\test.json");
var result = await JsonSerializer.DeserializeAsync<Root>(openStream);
// You need to get car2 Costo
var costo = result.Car2.Costo;
}
}
}
ProjFolder\Models\Root.cs
using System.Text.Json.Serialization;
namespace Whosebug.Models
{
public class Root
{
[JsonPropertyName("car1")]
public Car Car1 { get; set; }
[JsonPropertyName("car2")]
public Car Car2 { get; set; }
}
}
ProjFolder\Models\Car.cs
namespace Whosebug.Models
{
public class Car
{
public string CasaAutomobilistica { get; set; }
public string Modello { get; set; }
public string AnnoImmatricolazione { get; set; }
public string Targa { get; set; }
public int KM { get; set; }
public bool Finanziamento { get; set; }
public int Porte { get; set; }
public int Costo { get; set; }
}
}
{
"car1":
{
"CasaAutomobilistica": "Fiat",
"Modello": "500",
"AnnoImmatricolazione": "2017",
"Targa": "AZ978AG",
"KM": 120000,
"Finanziamento" : true,
"Porte" : 5,
"Costo" : 6000
},
"car2":
{
"CasaAutomobilistica": "BMW",
"Modello": "Serie 1",
"AnnoImmatricolazione": "2019",
"Targa": "BC978AG",
"KM": 150000,
"Finanziamento" : false,
"Porte" : 3,
"Costo" : 12000
}
}
我发现该函数可以正确地用于 JSON 解析:
var objs = JObject.Load(new JsonTextReader(new StreamReader(JsonPath)))
.SelectTokens("*")
.Select(t => JsonConvert.DeserializeObject<Cars>(t.ToString()));
但它在使用后不会释放文件(所以我不能将它用于其他功能)...我尝试使用函数 Close,但似乎无法处理该对象!
P.s。我已经检查了与该主题相关的 previous open-one question,但没有人谈论如何访问对象字段,而且如果我们计算我有超过 1 个对象,那么问题似乎有所不同......猜猜有人可以更好地解释它是如何工作的...
首先用using块读取文件并做JSON操作 最好将它放在一个单独的方法中,如下所示
private string readFile()
{
string buffer = null;
using (System.IO.FileStream stm = new
System.IO.FileStream("c:\YourFile.txt",System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.None))
{
using (System.IO.StreamReader rdr = new System.IO.StreamReader (stm))
{
buffer=rdr.ReadToEnd();
}
}
return buffer
}
private Object Deserialize(string content)
{
//do conversion here
}
来自 JSON.NET 网站 Read JSON from a File :
// read JSON directly from a file
using (StreamReader file = File.OpenText(@"c:\videogames.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
JObject o2 = (JObject)JToken.ReadFrom(reader);
}
问题的代码做了一些不必要的事情 - 它试图将已经反序列化的 JObject 序列化回 JSON,然后再次将其反序列化为 Car
。为什么不反序列化原始文件一次?
文档也在 Deserialize JSON from a file 中描述了这一点:
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(@"c:\movie.json"))
{
JsonSerializer serializer = new JsonSerializer();
Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie));
}
JSON 文档只能包含一个对象。如果文件内容如下所示:
{
"Movies":[{
"Title":"abc"
}, {
"Title":"abc"
}]
}
根对象应该包含一个 Movies
属性,其中包含一个 Movie[]
数组:
class RootObjedt
{
public Movie[] Movies{get;set;}
}
...
using (StreamReader file = File.OpenText(@"c:\movie.json"))
{
JsonSerializer serializer = new JsonSerializer();
var root = (Movie)serializer.Deserialize(file, typeof(RootObject));
var movies=root.Movies;
}
我建议您读取 json 数据异步,因为此方法具有将流作为输入的重载,因此您可以像这样在两个代码串中读取数据:
ProjFolder\Program.cs
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Whosebug.Models;
namespace Whosebug
{
class Program
{
static async Task Main(string[] args)
{
using var openStream = File.OpenRead(@"D:\Code\test.json");
var result = await JsonSerializer.DeserializeAsync<Root>(openStream);
// You need to get car2 Costo
var costo = result.Car2.Costo;
}
}
}
ProjFolder\Models\Root.cs
using System.Text.Json.Serialization;
namespace Whosebug.Models
{
public class Root
{
[JsonPropertyName("car1")]
public Car Car1 { get; set; }
[JsonPropertyName("car2")]
public Car Car2 { get; set; }
}
}
ProjFolder\Models\Car.cs
namespace Whosebug.Models
{
public class Car
{
public string CasaAutomobilistica { get; set; }
public string Modello { get; set; }
public string AnnoImmatricolazione { get; set; }
public string Targa { get; set; }
public int KM { get; set; }
public bool Finanziamento { get; set; }
public int Porte { get; set; }
public int Costo { get; set; }
}
}
{
"car1":
{
"CasaAutomobilistica": "Fiat",
"Modello": "500",
"AnnoImmatricolazione": "2017",
"Targa": "AZ978AG",
"KM": 120000,
"Finanziamento" : true,
"Porte" : 5,
"Costo" : 6000
},
"car2":
{
"CasaAutomobilistica": "BMW",
"Modello": "Serie 1",
"AnnoImmatricolazione": "2019",
"Targa": "BC978AG",
"KM": 150000,
"Finanziamento" : false,
"Porte" : 3,
"Costo" : 12000
}
}