Python递归读取目录
我想避免使用os.walk,我正在用一个递归函数来读取文件和文件夹,并把文件存储到一个字典里。
我去掉了os.chdir这个部分,但不知道为什么,现在这个函数把路径和文件名也拼在一起了,导致出现了错误:WindowsError: [Error 267] 目录名无效:'c:\data\foo\notes\*.*'。它在读取文件夹foo的时候,把路径和foo还有文件notes.txt拼在了一起,而不是应该是foo加上libary文件夹。
1 个回答
这对我来说似乎是有效的
import os
op = os.path
def fileRead(mydir):
data = {}
root = set()
for i in os.listdir(mydir):
path = op.join(mydir, i)
print(path)
if op.isfile(path):
data.setdefault(i, set())
root.add(op.relpath(mydir).replace("\\", "/"))
data[i] = root
else:
data.update(fileRead(path))
return data
d = fileRead("c:\python32\programas")
print(d)
不过我还是不太明白你为什么要使用设置根目录。我觉得这样做的目的是为了在两个目录中有相同文件时,能够保留所有的目录。但是这样并不奏效:每次更新都会删除重复键(文件名)的存储值。
这里有一段可以正常工作的代码,使用了一个叫做defaultdict的东西。你也可以用普通的字典(就像你的代码那样),但用defaultdict的话,你就不需要在使用某个键之前检查它是否已经初始化:
import os
from collections import defaultdict
op = os.path
def fileRead(mydir):
data = defaultdict(list)
for i in os.listdir(mydir):
path = op.join(mydir, i)
print(path)
if op.isfile(path):
root = op.relpath(mydir).replace("\\", "/")
data[i].append(root)
else:
for k, v in fileRead(path).items():
data[k].extend(v)
return data
d = fileRead("c:\python32\programas")
print(d)
补充:关于@hughdbrown的评论:
如果你用data.update(fileRead(path).items())
来更新数据,当我在我的电脑上调用fileRead("c:/python26/programas/pack")
时(现在在py26环境下):
c:/python26/programas/pack\copia.py
c:/python26/programas/pack\in pack.py
c:/python26/programas/pack\pack2
c:/python26/programas/pack\pack2\copia.py
c:/python26/programas/pack\pack2\in_pack2.py
c:/python26/programas/pack\pack2\pack3
c:/python26/programas/pack\pack2\pack3\copia.py
c:/python26/programas/pack\pack2\pack3\in3.pydefaultdict( 'list'>, {'in3.py': ['pack/pack2/pack3'], 'copia.py': ['pack/pack2/pack3'],
'in pack.py': ['pack'], 'in_pack2.py': ['pack/pack2']})
注意,在多个目录中重复的文件(比如copia.py)只会显示其中一个目录,通常是最深的那个。不过,当你使用以下代码时,所有的目录都会列出:
for k, v in fileRead(path).items(): data[k].extend(v)
c:/python26/programas/pack\copia.py
c:/python26/programas/pack\in pack.py
c:/python26/programas/pack\pack2
c:/python26/programas/pack\pack2\copia.py
c:/python26/programas/pack\pack2\in_pack2.py
c:/python26/programas/pack\pack2\pack3
c:/python26/programas/pack\pack2\pack3\copia.py
c:/python26/programas/pack\pack2\pack3\in3.pydefaultdict(, {'in3.py': ['pack/pack2/pack3'], 'copia.py': ['pack', 'pack/pack2', 'pack/pack2/pack3'],
'in pack.py': ['pack'], 'in_pack2.py': ['pack/pack2']})