文件系统树转为JSON

1 投票
1 回答
1905 浏览
提问于 2025-04-18 10:05

我正在尝试用Python把文件系统的树结构转换成json格式。

想象一下,我有这样的树结构:

plans/
|-- p1/
|   |-- p1_1.pdf
|   |-- p1_2.pdf
|   `-- test/
|       `-- test.jpg
|-- p2/
|   |-- p2_1.pdf
|   |-- p2_2.pdf
|   `-- test2/
|
`-- resume.pdf

我希望得到这样的json输出:

[
{
    "name": "p1",
    "type": "folder",
    "path": "/plans/p1",
    "tag": "org",
    "children": [
        {
            "name": "p1_1.pdf",
            "type": "file",
            "path": "/plans/p1/p1_1.pdf",
            "tag": "org"
        },
        {
            "name": "p1_2.pdf",
            "type": "file",
            "path": "/plans/p1/p1_2.pdf",
            "tag": "org"
        },
        {
            "name": "test",
            "type": "folder",
            "path": "/plans/p1/test",
            "tag": "org",
            "children": [
                {
                    "name": "test.jpg",
                    "type": "file",
                    "path": "/plans/p1/test/test.jpg",
                    "tag": "org"
                }
            ]
        }
    ]
},
{
    "name": "p2",
    "type": "folder",
    "path": "/plans/p2",
    "tag": "org",
    "children": [
        {
            "name": "p2_1.pdf",
            "type": "file",
            "path": "/plans/p2/p2_1.pdf",
            "tag": "org"
        },
        {
            "name": "p2_2.pdf",
            "type": "file",
            "path": "/plans/p2/p2_2.pdf",
            "tag": "org"
        },
        {
            "name": "test2",
            "type": "folder",
            "path": "/plans/p2/test2",
            "tag": "org",
            "children": [

            ]
        }
    ]
},
{
    "name": "resume.pdf",
    "type": "file",
    "path": "/plans/resume.pdf",
    "tag": "org"
}
]

我现在正在使用Python的os.walk()函数来遍历这个树结构,并创建字典的列表,以便用json.dumps()生成一个可以导出的列表,但我不知道怎么递归地做到这一点。

这里有一个简单的代码草稿:

def tree_to_json(rootdir):
main = []
for path, dirs, files in os.walk(rootdir):
        for curdir in dirs:
            child = []
            new_dir = {"name": curdir,
                       "type": "folder",
                       "path": path + os.sep + curdir,
                       "children": child}
            main.append(new_dir)
        for curfile in files:
            new_file = {"name": curfile,
                        "type": "file",
                        "path": path + os.sep + curfile}
            main.append(new_file)
return json.dumps(main, sort_keys=True, indent=2, separators=(',', ': '))

1 个回答

3

在编程中,解决问题的方法有很多种。这里有一个解决方案:

import json
from os import walk, path

def file_to_dict(fpath):
    return {
        'name': path.basename(fpath),
        'type': 'file',
        'path': fpath,
        'tag': 'org',
        }

def folder_to_dict(rootpath):
    return {
            'name': path.basename(rootpath),
            'type': 'folder',
            'path': rootpath,
            'tag': 'org',
            'children': [],
            }

def tree_to_dict(rootpath):
    root_dict = folder_to_dict(rootpath)
    root, folders, files = walk(rootpath).next()
    root_dict['children'] = [file_to_dict(path.sep.join([root, fpath])) for fpath in files]
    root_dict['children'] += [tree_to_dict(path.sep.join([root, folder])) for folder in folders]
    return root_dict

def tree_to_json(rootdir, pretty_print=True):
    root, folders, files = walk(rootdir).next()
    root_dict = [tree_to_dict(path.sep.join([root, folder])) for folder in folders]
    root_dict += [file_to_dict(path.sep.join([root, fpath])) for fpath in files]
    if pretty_print:
        js = json.dumps(root_dict, indent=4, encoding='utf-8')
    else:
        js = json.dumps(root_dict, encoding='utf-8')
    return js

print tree_to_json('/tmp/tree')

这是运行后的结果:

[
    {
        "path": "/tmp/tree/p1", 
        "tag": "org", 
        "type": "folder", 
        "name": "p1", 
        "children": [
            {
                "path": "/tmp/tree/p1/p1_1.pdf", 
                "tag": "org", 
                "type": "file", 
                "name": "p1_1.pdf"
            }, 
            {
                "path": "/tmp/tree/p1/p1_2.pdf", 
                "tag": "org", 
                "type": "file", 
                "name": "p1_2.pdf"
            }, 
            {
                "path": "/tmp/tree/p1/test", 
                "tag": "org", 
                "type": "folder", 
                "name": "test", 
                "children": [
                    {
                        "path": "/tmp/tree/p1/test/test.jpg", 
                        "tag": "org", 
                        "type": "file", 
                        "name": "test.jpg"
                    }
                ]
            }
        ]
    }, 
    {
        "path": "/tmp/tree/p2", 
        "tag": "org", 
        "type": "folder", 
        "name": "p2", 
        "children": [
            {
                "path": "/tmp/tree/p2/p2_1.pdf", 
                "tag": "org", 
                "type": "file", 
                "name": "p2_1.pdf"
            }, 
            {
                "path": "/tmp/tree/p2/p2_2.pdf", 
                "tag": "org", 
                "type": "file", 
                "name": "p2_2.pdf"
            }, 
            {
                "path": "/tmp/tree/p2/test2", 
                "tag": "org", 
                "type": "folder", 
                "name": "test2", 
                "children": []
            }
        ]
    }, 
    {
        "path": "/tmp/tree/resume.pdf", 
        "tag": "org", 
        "type": "file", 
        "name": "resume.pdf"
    }
]

撰写回答