Reputation: 21
I use os.listdir() and This code can traverse system directory structure, then generate a json file to django front-end of easyui call display tree UI:
def CreateDirTree(path,file_json):
global id_num
id_num=0
def createDict(path):
global id_num
tree_list=[]
pathList = os.listdir(path)
for i,item in enumerate(pathList):
id_num+=1
children_map={}
children_map['id']=id_num
children_map['text']=item
if os.path.isdir(os.path.join(path,item)):
path = os.path.join(path,item)
print "directory:",path
tmp_listdir=os.listdir(path)
if len(tmp_listdir) != 0:
children_map['state']='closed'
children_map['children'] = createDict(path)
tree_list.append(children_map)
path = '\\'.join(path.split('\\')[:-1])
else:
tree_list.append(children_map)
print children_map
return tree_list
tree_list=createDict(path)
fjson = json.dumps(tree_list,ensure_ascii=False,sort_keys=False)
with open(file_json,'w') as lf:
lf.write(fjson)
##end
CreateDirTree("D:\\all_source\\somesite","123.json")
run and result is:
directory: D:\all_source\somesite\a
file is: b.txt
file is: oo.txt
file is: a.txt
directory: D:\all_source\somesite\b
file is: 123.txt
file is: b.txt
directory: D:\all_source\somesite\c
file is: yyt.txt
directory: D:\all_source\somesite\c\z
file is: c.txt
file is: e.txt
But I want to effect is:
directory: D:\all_source\somesite\a
a subdir files: 123.txt
a subdir files: abc.txt
directory: D:\all_source\somesite\b
directory: D:\all_source\somesite\c
directory: D:\all_source\somesite\c\z
file is: a.txt
file is: b.txt
file is: c.txt
file is: e.txt
first sorted by directory then sorted by files, How to do? please help me,thanks!
Upvotes: 1
Views: 2427
Reputation: 4679
Here is a function to create the structure without a global
variable and without calling os.listdir()
twice for each directory:
import os
from itertools import count
def create_dir_tree(path):
ids = count(0)
def recurse(path):
names = list()
for name in os.listdir(path):
full_name = os.path.join(path, name)
names.append((os.path.isdir(full_name), name, full_name))
names.sort(key=lambda n: (not n[0], n[1]))
result = list()
for is_dir, name, full_name in names:
item = {'id': next(ids), 'text': name}
if is_dir:
children = recurse(full_name)
if children:
item['state'] = 'closed'
item['children'] = children
result.append(item)
return result
return recurse(path)
Like the original code one can't tell if an entry is a filename or an empty directory from the created data structure.
Upvotes: 2
Reputation: 2414
Create a list for directories and another for files and iterate over their concatenation. Adjusting from your code:
(...)
# List of directories only
dirlist = [x for x in os.listdir(path) if os.path.isdir(os.path.join(path, x))]
# List of files only
filelist = [x for x in os.listdir(path) if not os.path.isdir(os.path.join(path, x))]
for i,item in enumerate(dir_list + filelist):
(...)
This will start with directories and their subdirectories, and then move to the files
Upvotes: 4