Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.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# 将目录路径转换为JSON目录树表示形式_C#_Json_Tree_Filepath - Fatal编程技术网

C# 将目录路径转换为JSON目录树表示形式

C# 将目录路径转换为JSON目录树表示形式,c#,json,tree,filepath,C#,Json,Tree,Filepath,我有一个文件路径的示例输出,这只是问题的一个示例 新建文本Document.txt 新建文件夹/ 新建文件夹/README.txt 我想将其转换为以下JSON { "Data":"/", "Nodes":[ { "Data":"New Folder", "Nodes":[ { "Data":"New Text Document.txt" }

我有一个文件路径的示例输出,这只是问题的一个示例

新建文本Document.txt
新建文件夹/
新建文件夹/README.txt

我想将其转换为以下JSON

{
   "Data":"/",
   "Nodes":[
      {
         "Data":"New Folder",
         "Nodes":[
            {
               "Data":"New Text Document.txt"
            }
         ]
      },
      {
         "Data":"New Text Document.txt",
         "Nodes":[
            ""
         ]
      }
   ]
} 
我的节点类如下

public class Node
    {
        public Node(string fileName)
        {
            Nodes = new List<Node>();
            Data = fileName;
        }

        public List<Node> Nodes { get; set; }

        public string Data { get; set; }
    }
公共类节点
{
公共节点(字符串文件名)
{
节点=新列表();
数据=文件名;
}
公共列表节点{get;set;}
公共字符串数据{get;set;}
}
我试图找出算法,如何将中的文件路径表示为一个节点类,稍后将对其进行序列化以获得JSON。如果有任何其他方法将文件路径表示为目录树结构的JSON,请建议

using System.Web.Script.Serialization; ///name space to use

    JavaScriptSerializer js = new JavaScriptSerializer();
      string json = js.Serialize(pass node class object here);
下面的代码应该给出所需的目录结构

static void Main(string[] args)
{
    string path = @"path where to check";
    Node n = new Node();
    n.Nodes = new List<Node>();
    GetNodes(path, n);
    JavaScriptSerializer js = new JavaScriptSerializer();
    string json = js.Serialize(n);
}

public static void GetNodes(string path, Node node)
{
    if (File.Exists(path))
    {
        node = new Node(path);
    }
    else if (Directory.Exists(path))
    {
        node.Data = "\\";
        GetFiles(path, node);

        foreach ( string item in Directory.GetDirectories(path))
        {
            Node n = new Node();
            n.Nodes = new List<Node>();
            n.Data = item;
            GetFiles(path, n);
            node.Nodes.Add(n);
        }
    }
}

public static void GetFiles(string path, Node node)
{
    foreach (string item in Directory.GetFiles(path))
    {
        node.Nodes.Add(new Node(item));
    }

}

public class Node
{
    public Node()
    { }
    public Node(string fileName)
    {
        Nodes = new List<Node>();
        Data = fileName;
    }

    public List<Node> Nodes { get; set; }

    public string Data { get; set; }
}
static void Main(字符串[]args)
{
字符串路径=@“要检查的路径”;
节点n=新节点();
n、 节点=新列表();
GetNodes(路径,n);
JavaScriptSerializer js=新的JavaScriptSerializer();
字符串json=js.Serialize(n);
}
公共静态void GetNodes(字符串路径,节点节点)
{
if(File.Exists(path))
{
节点=新节点(路径);
}
else if(目录存在(路径))
{
node.Data=“\\”;
获取文件(路径、节点);
foreach(Directory.GetDirectories(path)中的字符串项)
{
节点n=新节点();
n、 节点=新列表();
n、 数据=项目;
GetFiles(路径,n);
node.Nodes.Add(n);
}
}
}
公共静态void GetFiles(字符串路径、节点)
{
foreach(Directory.GetFiles(path)中的字符串项)
{
node.Nodes.Add(新节点(项));
}
}
公共类节点
{
公共节点()
{ }
公共节点(字符串文件名)
{
节点=新列表();
数据=文件名;
}
公共列表节点{get;set;}
公共字符串数据{get;set;}
}

我终于抽出时间为您制作了一个样品。这应该是一个可良好扩展的递归解决方案。:)

static void Main(字符串[]args)
{
节点根=新节点(“/”);
AddNode(“New Text Document.txt”,root);
AddNode(“新文件夹/”,根目录);
AddNode(“新文件夹/README.txt”,根目录);
Console.ReadKey();
}
公共类节点
{
公共节点(){Nodes=new List();}
公共节点(字符串文件名)
{
节点=新列表();
数据=文件名;
}
公共节点FindNode(字符串数据)
{
if(this.Nodes==null | |!this.Nodes.Any()){return null;}
//检查节点列表以查看是否存在任何已存在的节点
返回此节点
.FirstOrDefault(n=>String.Equals(n.Data,Data,StringComparison.CurrentCultureIgnoreCase));
}
公共字符串数据{get;set;}
公共列表节点{get;set;}
}
公共静态节点AddNode(字符串文件路径,节点根节点)
{
//这将为您创建从文件路径递归所需的队列
var tokens=filePath.Split('/').ToList();
//如果您拆分一个以/结尾的文件夹,它会在结尾留下一个空字符串,我们希望将其删除
if(String.IsNullOrWhiteSpace(tokens.Last()){tokens.Remove(“”;}
返回AddNode(新队列(令牌),rootNode);
}
专用静态节点AddNode(队列令牌、节点rootNode)
{
//基本案例->未找到节点且令牌已丢失:(
if(tokens==null | |!tokens.Any())
{
返回null;
}
//获取当前令牌,在tokens对象中只保留未搜索的令牌
字符串current=tokens.Dequeue();
//创建节点(如果尚未存在)
Node foundNode=rootNode.FindNode(当前);
if(foundNode!=null)
{
//节点存在!递归
返回AddNode(令牌、foundNode);
}
其他的
{
//节点不存在!手动添加并递归
Node newNode=newNode(){Data=current};
rootNode.Nodes.Add(newNode);
返回AddNode(令牌、newNode);
}
}

为什么不直接使用JSON serializer?我正在序列化节点类,但我的问题是,我无法将字符串路径转换为节点类表示形式,以便在以后对其进行序列化。您应该在问题中更清楚地说明这就是问题所在。您应该能够拆分字符“/”上的路径字符串,然后遍历每个t好的,如果子节点不存在,就创建它。以前使用过递归吗?:)我可以很快编写一个示例。问题不在对象序列化中。问题是如何将字符串路径转换为节点对象。对于本例,这里没有算法Node root=new Node(“/”);添加(新节点(“new Text Document.txt”);添加(新节点(“新文件夹”);root.Nodes[0].Nodes.Add(新节点(“new Text Document.txt”);在这之后,如果我像你所说的那样序列化Node对象,我会得到我想要的结果,而这并不是我想要的。我不能使用Directory类,因为我正在处理zip文件,但我将尝试重新生成您的代码,谢谢您的一段代码;它可以工作,但需要安装一个参考:System.Web.extensions谢谢:)这就是我要找的
static void Main(string[] args)
{
    Node root = new Node("/");
    AddNode("New Text Document.txt", root);
    AddNode("New folder/", root);
    AddNode("New folder/README.txt", root);

    Console.ReadKey();
}

public class Node
{
    public Node() { Nodes = new List<Node>(); }
    public Node(string fileName)
    {
        Nodes = new List<Node>();
        Data = fileName;
    }

    public Node FindNode(string data)
    {
        if (this.Nodes == null || !this.Nodes.Any()) { return null; }

        // check Node list to see if there are any that already exist
        return this.Nodes
            .FirstOrDefault(n => String.Equals(n.Data, data, StringComparison.CurrentCultureIgnoreCase));
    }

    public string Data { get; set; }
    public List<Node> Nodes { get; set; }
}

public static Node AddNode(string filePath, Node rootNode)
{
    // convenience method. this creates the queue that we need for recursion from the filepath for you
    var tokens = filePath.Split('/').ToList();

    // if you split a folder ending with / it leaves an empty string at the end and we want to remove that
    if (String.IsNullOrWhiteSpace(tokens.Last())) { tokens.Remove(""); }

    return AddNode(new Queue<string>(tokens), rootNode);
}

private static Node AddNode(Queue<string> tokens, Node rootNode)
{
    // base case -> node wasnt found and tokens are gone  :(
    if (tokens == null || !tokens.Any())
    {
        return null;
    }

    // get current token, leaving only unsearched ones in the tokens object
    string current = tokens.Dequeue();

    // create node if not already exists
    Node foundNode = rootNode.FindNode(current);
    if (foundNode != null)
    {
        // node exists! recurse
        return AddNode(tokens, foundNode);
    }
    else
    {
        // node doesnt exist! add it manually and recurse
        Node newNode = new Node() { Data = current };
        rootNode.Nodes.Add(newNode);
        return AddNode(tokens, newNode);
    }
}