使用 Json.net LINQ 从目录创建文件树
Creating A Filetree from a directory with Json.net LINQ
使用以下代码:
static void Main(string[] args)
{
JObject fileSystemTree = CreateFileSystemJsonTree("C:/DirectoryTree");
Console.WriteLine(fileSystemTree);
Console.WriteLine("------");
//
// Write it out to a file
//
System.IO.File.WriteAllText(@"C:\jsontree.txt", fileSystemTree.ToString());
Console.ReadLine();
}
static JObject joNew = new JObject();
static JObject CreateFileSystemJsonTree(string source)
{
//
// Build a list of all the IPs
//
//Console.WriteLine(source);
using (var poiDbContext = new poiDbEntities())
{
DirectoryInfo di = new DirectoryInfo(source);
{
joNew = new JObject(
new JProperty(di.Name, new JArray(Directory.GetDirectories(source).Select(d => CreateFileSystemJsonTree(d)))),
new JProperty("files", new JArray(di.GetFiles().Select(fi => new JObject(new JProperty(fi.Name, GetText(fi.Name)))))));
}
Console.WriteLine(joNew);
}
return joNew;
}
public static string GetText(string fiName)
{
using (var poiDbContext = new poiDbEntities())
{
string indexNameBody = fiName.Substring(0, fiName.LastIndexOf('.'));
var indexResult = "test"; // dummied up for use by evaluators
return indexResult.Trim();
}
}
我正在尝试使用递归从系统目录创建文件树。我有这个与 XML 一起工作,但更喜欢 JSON 树。问题是 txt 文件出现,而不是父级的 [],它代表最低的文件夹,而是被添加为 JsonProperties,文本名称我添加为 "files"(我不想要)。另外,即使没有文件,例如在空文件夹中,也会生成 "files"。系统生成的代码段后跟可能需要的代码段。
"Sports": [
{
"NBA": [],
"files": [] // Undesirable--The folder is empty``
},``
两个片段:
{
"Politics": [
{
"PresCandidates": [
{
"Republican": [], // Notice the files are not in array within the [] of the Republican
"files": [
{
"carson_ben_s.txt": "Ben Carson"
},
{
"trump_donald_j.txt": "Donald Trump"
},
{
"walker_scott_k.txt": "Scott Walker"
}
]
}
]
}
],
"Politics": [ // The desired format
{
"PresCandidates": [
{
"Republican": [
{
"carson_ben_s.txt": "Ben Carson"
},
{
"trump_donald_j.txt": "Donald Trump"
},
{
"walker_scott_k.txt": "Scott Walker"
}
],
{
我不确定我是否理解您要创建的 JSON。如果您正在寻找一组嵌套的 JSON 对象,其中每个 属性 名称对应于文件或目录名称,并且对于文件,属性 值由某些回调方法给出,而对于子目录,该值是一个递归包含子目录所有内容的对象的对象,您可以这样做:
public static class DirectoryInfoExtensions
{
public static JObject ToJson<TResult>(this DirectoryInfo info, Func<FileInfo, TResult> getData)
{
return new JObject
(
info.GetFiles().Select(f => new JProperty(f.Name, getData(f))).Concat(info.GetDirectories().Select(d => new JProperty(d.Name, d.ToJson(getData))))
);
}
}
然后像这样使用它:
string path = @"C:\Program Files (x86)\Microsoft Visual Studio 9.0";
var di = new DirectoryInfo(path);
Debug.WriteLine(di.ToJson(f => f.LastWriteTimeUtc));
产生如下输出:
{
"redist.txt": "2007-10-16T21:56:34Z",
"Common7": {
"IDE": {
"Brief.vsk": "2007-06-20T21:55:14Z",
"WinFxCustomControlTemplateWizard.dll": "2008-07-30T14:06:58Z",
"1033": {
"cmddefui.dll": "2008-07-30T14:06:58Z",
"Microsoft.VisualStudio.DesignUI.dll": "2008-07-30T14:06:58Z",
"Microsoft.VisualStudio.EditorsUI.dll": "2008-07-30T14:06:58Z",
Many values removed,
"VsWizUI.dll": "2008-07-30T14:06:58Z",
"WindowsFormsIntegration.PackageUI.dll": "2008-07-30T14:06:58Z"
},
"en": {
"Microsoft.VisualStudio.Package.LanguageService.xml": "2007-03-02T04:30:40Z",
"Microsoft.VisualStudio.Shell.Design.xml": "2007-03-06T04:40:44Z",
"Microsoft.VisualStudio.Shell.xml": "2007-03-06T04:40:44Z"
},
"ExceptionAssistantContent": {
"1033": {
"DefaultContent.xml": "2007-09-03T05:11:44Z"
}
}
}
}
}
这是你想要的吗?您的部分 JSON 示例包含数组,但我看不到您在哪里或如何需要它们。
如果这不是您想要的,您能否澄清一下所需的 JSON 格式?
顺便说一下,如果你有 XML 工作,你总是可以使用 JsonConvert.SerializeXNode()
。
你的想法很成功。谢谢你。我有一个评论和另一个问题。我知道 json 文件树没有标准格式。但是,每个文件夹都应该以 [] 开头和结尾,因为它们是 而不是 "leaf" 节点,这难道没有意义吗?我试图修改你的代码,使它看起来像下面这样,但没有成功。我添加了时间戳。
{
"7/28/2015 6:00:45 PM": // Modified by hand
lennane_ava_l.txt": "Ava Lennane",
"ALists": [ // Modified by hand
"clinton_hillary_r.txt": "Hillary Clinton",
"depasquale_vincent_99.txt": "Vincent Depasquale",
"trump_donald_j.txt": "Donald Trump",
"zz_kilroy_99.txt": "Kilroy",
"Criminals": [], // Modified by hand
"Entertainment": [], // Modified by hand
"Politics": [ // Modified by hand
"clinton_hillary_r.txt": "Hillary Clinton",
"lennane_james_p.txt": "Jim Lennane",
"trump_donald_j.txt": "Donald Trump",
"PresCandidates": { // Unmodified
"clinton_hillary_r.txt": "Hillary Clinton",
"trump_donald_j.txt": "Donald Trump",
"Democrat": { // Unmodified
"clinton_hillary_r.txt": "Hillary Clinton"
},
"Other": {},
"Republican": {
"carson_ben_s.txt": "Ben Carson",
"lennane_james_p.txt": "Jim Lennane",
"trump_donald_j.txt": "Donald Trump",
"walker_scott_k.txt": "Scott Walker"
使用以下代码:
static void Main(string[] args)
{
JObject fileSystemTree = CreateFileSystemJsonTree("C:/DirectoryTree");
Console.WriteLine(fileSystemTree);
Console.WriteLine("------");
//
// Write it out to a file
//
System.IO.File.WriteAllText(@"C:\jsontree.txt", fileSystemTree.ToString());
Console.ReadLine();
}
static JObject joNew = new JObject();
static JObject CreateFileSystemJsonTree(string source)
{
//
// Build a list of all the IPs
//
//Console.WriteLine(source);
using (var poiDbContext = new poiDbEntities())
{
DirectoryInfo di = new DirectoryInfo(source);
{
joNew = new JObject(
new JProperty(di.Name, new JArray(Directory.GetDirectories(source).Select(d => CreateFileSystemJsonTree(d)))),
new JProperty("files", new JArray(di.GetFiles().Select(fi => new JObject(new JProperty(fi.Name, GetText(fi.Name)))))));
}
Console.WriteLine(joNew);
}
return joNew;
}
public static string GetText(string fiName)
{
using (var poiDbContext = new poiDbEntities())
{
string indexNameBody = fiName.Substring(0, fiName.LastIndexOf('.'));
var indexResult = "test"; // dummied up for use by evaluators
return indexResult.Trim();
}
}
我正在尝试使用递归从系统目录创建文件树。我有这个与 XML 一起工作,但更喜欢 JSON 树。问题是 txt 文件出现,而不是父级的 [],它代表最低的文件夹,而是被添加为 JsonProperties,文本名称我添加为 "files"(我不想要)。另外,即使没有文件,例如在空文件夹中,也会生成 "files"。系统生成的代码段后跟可能需要的代码段。
"Sports": [
{
"NBA": [],
"files": [] // Undesirable--The folder is empty``
},``
两个片段:
{
"Politics": [
{
"PresCandidates": [
{
"Republican": [], // Notice the files are not in array within the [] of the Republican
"files": [
{
"carson_ben_s.txt": "Ben Carson"
},
{
"trump_donald_j.txt": "Donald Trump"
},
{
"walker_scott_k.txt": "Scott Walker"
}
]
}
]
}
],
"Politics": [ // The desired format
{
"PresCandidates": [
{
"Republican": [
{
"carson_ben_s.txt": "Ben Carson"
},
{
"trump_donald_j.txt": "Donald Trump"
},
{
"walker_scott_k.txt": "Scott Walker"
}
],
{
我不确定我是否理解您要创建的 JSON。如果您正在寻找一组嵌套的 JSON 对象,其中每个 属性 名称对应于文件或目录名称,并且对于文件,属性 值由某些回调方法给出,而对于子目录,该值是一个递归包含子目录所有内容的对象的对象,您可以这样做:
public static class DirectoryInfoExtensions
{
public static JObject ToJson<TResult>(this DirectoryInfo info, Func<FileInfo, TResult> getData)
{
return new JObject
(
info.GetFiles().Select(f => new JProperty(f.Name, getData(f))).Concat(info.GetDirectories().Select(d => new JProperty(d.Name, d.ToJson(getData))))
);
}
}
然后像这样使用它:
string path = @"C:\Program Files (x86)\Microsoft Visual Studio 9.0";
var di = new DirectoryInfo(path);
Debug.WriteLine(di.ToJson(f => f.LastWriteTimeUtc));
产生如下输出:
{
"redist.txt": "2007-10-16T21:56:34Z",
"Common7": {
"IDE": {
"Brief.vsk": "2007-06-20T21:55:14Z",
"WinFxCustomControlTemplateWizard.dll": "2008-07-30T14:06:58Z",
"1033": {
"cmddefui.dll": "2008-07-30T14:06:58Z",
"Microsoft.VisualStudio.DesignUI.dll": "2008-07-30T14:06:58Z",
"Microsoft.VisualStudio.EditorsUI.dll": "2008-07-30T14:06:58Z",
Many values removed,
"VsWizUI.dll": "2008-07-30T14:06:58Z",
"WindowsFormsIntegration.PackageUI.dll": "2008-07-30T14:06:58Z"
},
"en": {
"Microsoft.VisualStudio.Package.LanguageService.xml": "2007-03-02T04:30:40Z",
"Microsoft.VisualStudio.Shell.Design.xml": "2007-03-06T04:40:44Z",
"Microsoft.VisualStudio.Shell.xml": "2007-03-06T04:40:44Z"
},
"ExceptionAssistantContent": {
"1033": {
"DefaultContent.xml": "2007-09-03T05:11:44Z"
}
}
}
}
}
这是你想要的吗?您的部分 JSON 示例包含数组,但我看不到您在哪里或如何需要它们。
如果这不是您想要的,您能否澄清一下所需的 JSON 格式?
顺便说一下,如果你有 XML 工作,你总是可以使用 JsonConvert.SerializeXNode()
。
你的想法很成功。谢谢你。我有一个评论和另一个问题。我知道 json 文件树没有标准格式。但是,每个文件夹都应该以 [] 开头和结尾,因为它们是 而不是 "leaf" 节点,这难道没有意义吗?我试图修改你的代码,使它看起来像下面这样,但没有成功。我添加了时间戳。
{
"7/28/2015 6:00:45 PM": // Modified by hand
lennane_ava_l.txt": "Ava Lennane",
"ALists": [ // Modified by hand
"clinton_hillary_r.txt": "Hillary Clinton",
"depasquale_vincent_99.txt": "Vincent Depasquale",
"trump_donald_j.txt": "Donald Trump",
"zz_kilroy_99.txt": "Kilroy",
"Criminals": [], // Modified by hand
"Entertainment": [], // Modified by hand
"Politics": [ // Modified by hand
"clinton_hillary_r.txt": "Hillary Clinton",
"lennane_james_p.txt": "Jim Lennane",
"trump_donald_j.txt": "Donald Trump",
"PresCandidates": { // Unmodified
"clinton_hillary_r.txt": "Hillary Clinton",
"trump_donald_j.txt": "Donald Trump",
"Democrat": { // Unmodified
"clinton_hillary_r.txt": "Hillary Clinton"
},
"Other": {},
"Republican": {
"carson_ben_s.txt": "Ben Carson",
"lennane_james_p.txt": "Jim Lennane",
"trump_donald_j.txt": "Donald Trump",
"walker_scott_k.txt": "Scott Walker"