Il modo corretto per evitare di allocare l'elenco di nomi utilizzando os.listdir consiste nell'utilizzare la funzione di livello os come ha detto @Charles Duffy.
Ispirato da questo altro post: List files in a folder as a stream to begin process immediately
ho aggiunto come risolvere il specifica domanda OP e utilizzato la versione rientrante delle funzioni.
from ctypes import CDLL, c_char_p, c_int, c_long, c_ushort, c_byte, c_char, Structure, POINTER, byref, cast, sizeof, get_errno
from ctypes.util import find_library
class c_dir(Structure):
"""Opaque type for directory entries, corresponds to struct DIR"""
pass
class c_dirent(Structure):
"""Directory entry"""
# FIXME not sure these are the exactly correct types!
_fields_ = (
('d_ino', c_long), # inode number
('d_off', c_long), # offset to the next dirent
('d_reclen', c_ushort), # length of this record
('d_type', c_byte), # type of file; not supported by all file system types
('d_name', c_char * 4096) # filename
)
c_dirent_p = POINTER(c_dirent)
c_dirent_pp = POINTER(c_dirent_p)
c_dir_p = POINTER(c_dir)
c_lib = CDLL(find_library("c"))
opendir = c_lib.opendir
opendir.argtypes = [c_char_p]
opendir.restype = c_dir_p
readdir_r = c_lib.readdir_r
readdir_r.argtypes = [c_dir_p, c_dirent_p, c_dirent_pp]
readdir_r.restype = c_int
closedir = c_lib.closedir
closedir.argtypes = [c_dir_p]
closedir.restype = c_int
import errno
def listdirx(path):
"""
A generator to return the names of files in the directory passed in
"""
dir_p = opendir(path)
if not dir_p:
raise IOError()
entry_p = cast(c_lib.malloc(sizeof(c_dirent)), c_dirent_p)
try:
while True:
res = readdir_r(dir_p, entry_p, byref(entry_p))
if res:
raise IOError()
if not entry_p:
break
name = entry_p.contents.d_name
if name not in (".", ".."):
yield name
finally:
if dir_p:
closedir(dir_p)
if entry_p:
c_lib.free(entry_p)
if __name__ == '__main__':
import sys
path = sys.argv[1]
max_per_dir = int(sys.argv[2])
for idx, entry in enumerate(listdirx(path)):
if idx >= max_per_dir:
break
print entry
C'è qualcosa di distinto nei nomi delle directory contenenti sequenze di immagini DPX? –
Se si desidera leggere le directory di grandi dimensioni in modo incrementale (ovvero non solo interrompere la ricorsione, ma nemmeno leggere i loro singoli contenuti), potrebbe essere necessario utilizzare qualcosa come le soluzioni descritte in http: // StackOverflow.it/questions/4403598/list-files-in-a-folder-come-a-stream-to-begin-process-immediatamente –
Alcune directory hanno 'dpx' nel nome, ma non tutte :(@ charles, questo esempio funzionerà per me. Voglio uscire da un elenco se incrocio un DPX, in questo modo potrei evitare di scorrere tra 100.000 nomi di file, il che richiede molto tempo. – Jamie