如何将文件路径数组转换为分层JSON结构 [英] How to transform an array of file paths into a hierarchical JSON structure

查看:106
本文介绍了如何将文件路径数组转换为分层JSON结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过给定机器所有文件和路径的数组来创建机器目录结构的JSON。

I am trying to create a JSON of a machine's directory structure given an array of all its files and paths.

该数组看起来像这样:

string[] dirArray = {
"./proc/15/task/15/exe",
"./proc/15/task/15/mounts/mounts.xml",
"./proc/15/task/15/mountinfo/mountinfo.xml",
"./proc/15/task/15/clear_refs/clear_ref.xml",
"./proc/14/loginuid/loginuid.xml",
"./proc/14/sessionid/sessionid.xml",
"./proc/14/coredump_filter/coredump_filter.xml",
"./proc/14/io/io.xml"
}

我想要的目标JSON是这样的:

The target JSON I am aiming for is something like this:

{
   ".":
   {
        "file":
        {
            "name":"fileInRoot.xml"
        },
        "proc":
        {
            "file":
            {
                "name":"fileInProc.xml"
            },
            "15":
            {
                "file":
                {
                    "name":"fileIn15.xml"
                },
                "task":
                {
                    "file":
                    {
                        "name":"fileInTask.xml"
                    },
                    "15":
                    {
                        "file":
                        {
                            "name":"fileInTask.xml"
                        },
                        "mounts":
                        {
                            "file":
                            {
                                "name":"fileInMounts.xml"
                            }
                        },
                        "mountsInfo":
                        {
                            "file":
                            {
                                "name":"fileInMountsInfo.xml"
                            }
                        },
                        "clear_refs":
                        {
                            "file":
                            {
                                "name":"fileInClear_Refs.xml"
                            }
                        }                   
                    }
                }
            },
            "14":
            {
                "file":
                {
                    "name":"fileIn14.xml"
                },
                "task":
                {
                    "file":
                    {
                        "name":"fileInTask.xml"
                    },
                    "loginUid":
                    {
                        "file":
                        {
                            "name":"fileInloginUid.xml"
                        }                   
                    },
                    "sessionid":
                    {
                        "file":
                        {
                            "name":"fileInsessionid.xml"
                        }                   
                    },
                    "coreDump_filter":
                    {
                        "file":
                        {
                            "name":"fileIncoreDump_filter.xml"
                        }                   
                    },
                    "io":
                    {
                        "file":
                        {
                            "name":"fileInIo.xml"
                        }                   
                    }
                }
            }
        }
    }
}

I想要创建一个JSON文件,以允许JSON的使用者组件浏览此目录结构。我一直在尝试使用目录文件路径类,但也许最好的方法是在遍历数组时使用java.serializor(?)类构造JSON,并在解析时解析其目录和文件?

I want to create a JSON file that allows consumer component of the JSON to navigate through this directory structure. I have been trying to use the Directory, File and Path classes but perhaps the best way is to use the java.serializor(?) class to construct the JSON as I loop through the array, parsing its directories and files as i go?

推荐答案

我认为我将把这个问题分成两部分来解决。首先,我们需要一种解析目录/文件路径数组并将其放入层次结构的方法。其次,我们需要采用该结构并将其转换为JSON。 (从您的问题中我不能完全确定您要使用哪个序列化程序,因此对于此答案,我将假设 Json.Net 没关系。)

I think I would approach this problem by breaking it into two parts. First, we need a way to parse apart the array of directory/file paths and put it into a hierarchical structure. Second, we need to take that structure and turn it into JSON. (I wasn't entirely sure from your question which serializer you wanted to use, so for this answer I will assume that Json.Net is OK.)

对于第一部分,我将创建一个 Dir 类,该类具有名称,字典子目录(以便于查找)和一组文件。我们可以在此类中创建一个方法,该方法将解析路径并找到或添加适当的子对象。

For the first part, I would create a Dir class which has a name, a dictionary of child directories (for easy lookup) and a set of files. We can make a method in this class which will parse apart a path and either find or add the appropriate child objects.

class Dir
{
    public string Name { get; set; }
    public Dictionary<string, Dir> Dirs { get; set; }
    public HashSet<string> Files { get; set; }

    public Dir(string name)
    {
        Name = name;
        Dirs = new Dictionary<string, Dir>();
        Files = new HashSet<string>();
    }

    public Dir FindOrCreate(string path, bool mightBeFile = true)
    {
        int i = path.IndexOf('/');
        if (i > -1)
        {
            Dir dir = FindOrCreate(path.Substring(0, i), false);
            return dir.FindOrCreate(path.Substring(i + 1), true);
        }

        if (path == "") return this;

        // if the name is at the end of a path and contains a "." 
        // we assume it is a file (unless it is "." by itself)
        if (mightBeFile && path != "." && path.Contains("."))
        {
            Files.Add(path);
            return this;
        }

        Dir child;
        if (Dirs.ContainsKey(path))
        {
            child = Dirs[path];
        }
        else
        {
            child = new Dir(path);
            Dirs.Add(path, child);
        }
        return child;
    }
}

使用此类,我们可以轻松地遍历 dirArray 在您的问题中给出,并建立目录层次结构:

Using this class, we can easily loop through the dirArray given in your question and make the directory hierarchy:

Dir root = new Dir("");
foreach (string dir in dirArray)
{
    root.FindOrCreate(dir);
}

因此,此时, root 现在具有整个目录层次结构。如果愿意,您可以直接使用Json.Net直接序列化此对象以获得合理的JSON结构。但是,这将比您在问题中描述的更加冗长。这是将要生成的JSON:

So at this point, root now has the entire directory hierarchy. If you wanted to, you could simply serialize this object directly with Json.Net to get a reasonable JSON structure. However, it will be a little more verbose than what you described in your question. Here is the JSON that would be produced:

{
  "Name": "",
  "Dirs": {
    ".": {
      "Name": ".",
      "Dirs": {
        "proc": {
          "Name": "proc",
          "Dirs": {
            "15": {
              "Name": "15",
              "Dirs": {
                "task": {
                  "Name": "task",
                  "Dirs": {
                    "15": {
                      "Name": "15",
                      "Dirs": {
                        "exe": {
                          "Name": "exe",
                          "Dirs": {},
                          "Files": []
                        },
                        "mounts": {
                          "Name": "mounts",
                          "Dirs": {},
                          "Files": [
                            "mounts.xml"
                          ]
                        },
                        "mountinfo": {
                          "Name": "mountinfo",
                          "Dirs": {},
                          "Files": [
                            "mountinfo.xml",
                            "moremountinfo.xml"
                          ]
                        },
                        "clear_refs": {
                          "Name": "clear_refs",
                          "Dirs": {},
                          "Files": [
                            "clear_ref.xml"
                          ]
                        }
                      },
                      "Files": []
                    }
                  },
                  "Files": []
                }
              },
              "Files": []
            },
            "14": {
              "Name": "14",
              "Dirs": {
                "loginuid": {
                  "Name": "loginuid",
                  "Dirs": {},
                  "Files": [
                    "loginuid.xml"
                  ]
                },
                "sessionid": {
                  "Name": "sessionid",
                  "Dirs": {},
                  "Files": [
                    "sessionid.xml"
                  ]
                },
                "coredump_filter": {
                  "Name": "coredump_filter",
                  "Dirs": {},
                  "Files": [
                    "coredump_filter.xml"
                  ]
                },
                "io": {
                  "Name": "io",
                  "Dirs": {},
                  "Files": [
                    "io.xml"
                  ]
                }
              },
              "Files": []
            }
          },
          "Files": []
        }
      },
      "Files": []
    }
  },
  "Files": []
}

要获取您想要的JSON,我们将需要一个 JsonConverter 类:

To get the JSON you are aiming for, we will need a JsonConverter class:

class DirConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Dir));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Dir dir = (Dir)value;
        JObject obj = new JObject();
        if (dir.Files.Count > 0)
        {
            JArray files = new JArray();
            foreach (string name in dir.Files)
            {
                files.Add(new JValue(name));
            }
            obj.Add("list_of_files", files);
        }
        foreach (var kvp in dir.Dirs)
        {
            obj.Add(kvp.Key, JToken.FromObject(kvp.Value, serializer));
        }
        obj.WriteTo(writer);
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

我们可以使用转换器来序列化目录层次结构:

We can serialize the directory hierarchy using the converter like this:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new DirConverter());
settings.Formatting = Formatting.Indented;

string json = JsonConvert.SerializeObject(root, settings);

这里是输出。请注意,我已将原始JSON中的文件属性更改为数组,并将其重命名为 list_of_files,以适应每个目录中每个注释包含多个文件的可能性。我还假设永远不会有一个名为 list_of_files的实际目录。如果可能,则需要将文件数组的名称更改为不会与任何目录名称冲突的其他名称。 (如果遇到错误 无法将属性list_of_files添加到Newtonsoft.Json.Linq.JObject。对象上已经存在具有相同名称的属性,这意味着您在您的数据中有一个名为 list_of_files的目录。)

Here is the output. Note that I changed the "file" properties in your original JSON to arrays, and renamed it to "list_of_files" to accommodate the possibility of multiple files per directory, per your comments. I am also assuming that there will never be an actual directory called "list_of_files". If that is a possibility, you would need to change the name of the files array to something else that will not collide with any of your directory names. (If you ever encounter an error that says "Can not add property list_of_files to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object" that means you have a directory somewhere in your data with the name "list_of_files".)

{
  ".": {
    "proc": {
      "15": {
        "task": {
          "15": {
            "exe": {},
            "mounts": {
              "list_of_files": [
                "mounts.xml"
              ]
            },
            "mountinfo": {
              "list_of_files": [
                "mountinfo.xml"
              ]
            },
            "clear_refs": {
              "list_of_files": [
                "clear_ref.xml"
              ]
            }
          }
        }
      },
      "14": {
        "loginuid": {
          "list_of_files": [
            "loginuid.xml"
          ]
        },
        "sessionid": {
          "list_of_files": [
            "sessionid.xml"
          ]
        },
        "coredump_filter": {
          "list_of_files": [
            "coredump_filter.xml"
          ]
        },
        "io": {
          "list_of_files": [
            "io.xml"
          ]
        }
      }
    }
  }
}

小提琴: https:// dotnetfiddle.net/ConJiu

这篇关于如何将文件路径数组转换为分层JSON结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆