使用Node.js将文件系统中的目录结构转换为JSON

hag*_*ope 57 javascript filesystems node.js d3.js

我有这样的文件结构:

root
|_ fruits
|___ apple
|______images
|________ apple001.jpg
|________ apple002.jpg
|_ animals
|___ cat
|______images
|________ cat001.jpg
|________ cat002.jpg
Run Code Online (Sandbox Code Playgroud)

我想,使用Javascript和Node.js,监听这个根目录和所有子目录,并创建一个镜像这个目录结构的JSON,每个节点包含类型,名称,路径和子节点:

data = [
  {
    type: "folder",
    name: "animals",
    path: "/animals",
    children: [
      {
        type: "folder",
        name: "cat",
        path: "/animals/cat",
        children: [
          {
            type: "folder",
            name: "images",
            path: "/animals/cat/images",
            children: [
              {
                type: "file",
                name: "cat001.jpg",
                path: "/animals/cat/images/cat001.jpg"
              }, {
                type: "file",
                name: "cat001.jpg",
                path: "/animals/cat/images/cat002.jpg"
              }
            ]
          }
        ]
      }
    ]
  }
];
Run Code Online (Sandbox Code Playgroud)

这是一个coffeescript JSON:

data = 
[
  type: "folder"
  name: "animals"
  path: "/animals"
  children  :
    [
      type: "folder"
      name: "cat"
      path: "/animals/cat"
      children:
        [
          type: "folder"
          name: "images"
          path: "/animals/cat/images"
          children: 
            [
              type: "file"
              name: "cat001.jpg"
              path: "/animals/cat/images/cat001.jpg"
            , 
              type: "file"
              name: "cat001.jpg"
              path: "/animals/cat/images/cat002.jpg"
            ]
        ]
    ]
]
Run Code Online (Sandbox Code Playgroud)

如何在django视图中获取这个json数据格式?(python)

Mii*_*kka 68

这是一个草图.错误处理留给读者练习.

var fs = require('fs'),
    path = require('path')

function dirTree(filename) {
    var stats = fs.lstatSync(filename),
        info = {
            path: filename,
            name: path.basename(filename)
        };

    if (stats.isDirectory()) {
        info.type = "folder";
        info.children = fs.readdirSync(filename).map(function(child) {
            return dirTree(filename + '/' + child);
        });
    } else {
        // Assuming it's a file. In real life it could be a symlink or
        // something else!
        info.type = "file";
    }

    return info;
}

if (module.parent == undefined) {
    // node dirTree.js ~/foo/bar
    var util = require('util');
    console.log(util.inspect(dirTree(process.argv[2]), false, null));
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的功能.我想最好使用path.join而不是'a +'/'+ b`.`return dirTree(path.join(filename,child));` (5认同)
  • 这在第一层很有用,但是,孩子们看起来像:孩子:[对象] ......你看到这里有什么问题吗? (3认同)
  • 是啊.创建的对象很好,但默认情况下,console.log仅将对象打印到有限的深度.我编辑了代码以打印完整的树. (3认同)

Asa*_*atz 21

它有一个NPM模块

https://www.npmjs.com/package/directory-tree

创建表示目录树的对象.

从:

photos
??? summer
?   ??? june
?       ??? windsurf.jpg
??? winter
    ??? january
        ??? ski.png
        ??? snowboard.jpg
Run Code Online (Sandbox Code Playgroud)

至:

{
  "path": "",
  "name": "photos",
  "type": "directory",
  "children": [
    {
      "path": "summer",
      "name": "summer",
      "type": "directory",
      "children": [
        {
          "path": "summer/june",
          "name": "june",
          "type": "directory",
          "children": [
            {
              "path": "summer/june/windsurf.jpg",
              "name": "windsurf.jpg",
              "type": "file"
            }
          ]
        }
      ]
    },
    {
      "path": "winter",
      "name": "winter",
      "type": "directory",
      "children": [
        {
          "path": "winter/january",
          "name": "january",
          "type": "directory",
          "children": [
            {
              "path": "winter/january/ski.png",
              "name": "ski.png",
              "type": "file"
            },
            {
              "path": "winter/january/snowboard.jpg",
              "name": "snowboard.jpg",
              "type": "file"
            }
          ]
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

用法

var tree = directoryTree('/some/path');
Run Code Online (Sandbox Code Playgroud)

您还可以按扩展程序进行过滤:

var filteredTree = directoryTree('/some/path', ['.jpg', '.png']);
Run Code Online (Sandbox Code Playgroud)

  • 这正是我所需要的。谢谢。效果很好。 (2认同)

Lif*_*ery 19

接受的答案有效,但它是同步的并且会严重损害您的性能,尤其是对于大型目录树.
我强烈建议您使用以下异步解决方案,它既快又无阻塞.
基于这里的并行解决方案.

var fs = require('fs');
var path = require('path');

var diretoryTreeToObj = function(dir, done) {
    var results = [];

    fs.readdir(dir, function(err, list) {
        if (err)
            return done(err);

        var pending = list.length;

        if (!pending)
            return done(null, {name: path.basename(dir), type: 'folder', children: results});

        list.forEach(function(file) {
            file = path.resolve(dir, file);
            fs.stat(file, function(err, stat) {
                if (stat && stat.isDirectory()) {
                    diretoryTreeToObj(file, function(err, res) {
                        results.push({
                            name: path.basename(file),
                            type: 'folder',
                            children: res
                        });
                        if (!--pending)
                            done(null, results);
                    });
                }
                else {
                    results.push({
                        type: 'file',
                        name: path.basename(file)
                    });
                    if (!--pending)
                        done(null, results);
                }
            });
        });
    });
};
Run Code Online (Sandbox Code Playgroud)

用法示例:

var dirTree = ('/path/to/dir');

diretoryTreeToObj(dirTree, function(err, res){
    if(err)
        console.error(err);

    console.log(JSON.stringify(res));
});
Run Code Online (Sandbox Code Playgroud)