4

100,000個のファイルを含むディレクトリを反復処理する方法を探しています。os.listdirこの関数は最初に指定されたパス全体からパスリストを取得するため、使用は非常に遅くなります。

最速のオプションは何ですか?

注:反対票を投じた人は、この状況に確実に直面したことはありません。

4

2 に答える 2

1

この他の質問は、コメントで重複として参照されてい
ました。フォルダ内のファイルをストリームとしてリストして、すぐにプロセスを開始します

...しかし、この例は半ば機能していないことがわかりました。これが私のために働く修正されたバージョンです:

from ctypes import CDLL, c_int, c_uint8, c_uint16, c_uint32, c_char, c_char_p, Structure, POINTER
from ctypes.util import find_library

import os

class c_dir(Structure):
    pass

class c_dirent(Structure):
    _fields_ = [ 
        ("d_fileno", c_uint32), 
        ("d_reclen", c_uint16),
        ("d_type", c_uint8), 
        ("d_namlen", c_uint8),
        ("d_name", c_char * 4096),
        # proper way of getting platform MAX filename size?
        # ("d_name", c_char * (os.pathconf('.', 'PC_NAME_MAX')+1) ) 
    ]

c_dirent_p = POINTER(c_dirent)
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

# FIXME Should probably use readdir_r here
readdir = c_lib.readdir
readdir.argtypes = [c_dir_p]
readdir.restype = c_dirent_p

closedir = c_lib.closedir
closedir.argtypes = [c_dir_p]
closedir.restype = c_int

def listdir(path):
    """
    A generator to return the names of files in the directory passed in
    """
    dir_p = opendir(".")
    try:
        while True:
            p = readdir(dir_p)
            if not p:
                break
            name = p.contents.d_name
            if name not in (".", ".."):
                yield name
    finally:
        closedir(dir_p)


if __name__ == "__main__":
    for name in listdir("."):
        print name
于 2012-08-31T00:22:39.887 に答える
0

ディレクトリ内の各ファイルに対して何をしていますか?os.listdirを使用することについては実際には選択の余地はないと思いますが、実行していることによっては、ファイルを並行して処理できる場合があります。たとえば、マルチプロセッシングライブラリのプールを使用して、より多くのPythonプロセスを生成し、各プロセスにファイルのより小さなサブセットを反復処理させることができます。

http://docs.python.org/library/multiprocessing.html

これはちょっとラフですが、私はそれが意味を理解していると思います...

import sys
import os
from processing import Pool

p = Pool(3)
def work(subsetOfFiles):
    for file in subsetOfFiles:
        with open(file, 'r') as f:
           #read file, do work
    return "data"

p.map(work, [[#subSetFiles1],[#subSetFiles2],[#subSetFiles3]])

一般的な考え方は、os.listdirからファイルのリストを取得することですが、100,000ファイルを1つずつ超えるのではなく、100,000ファイルを5,000ファイルの20リストに分割し、各プロセスで5,000ファイルを処理します。このアプローチの良い点の1つは、マルチコアシステムの現在の傾向から恩恵を受けることです。

于 2012-08-31T00:23:05.583 に答える