2012-05-04 8 views
5

मैं एक निर्देशिका को फिर से चलाना चाहता हूं, लेकिन अगर मैं 100 से अधिक फ़ाइलों वाली निर्देशिका से मुकाबला करता हूं तो मुझे किसी भी सूची में से पाइथन को तोड़ना है। असल में, मैं एक (.TXT) फ़ाइल खोज रहा हूं, लेकिन मैं बड़ी डीपीएक्स छवि अनुक्रमों (आमतौर पर 10,000 फाइलें) वाली निर्देशिकाओं से बचना चाहता हूं। चूंकि डीपीएक्स निर्देशिका में किसी उप निर्देशिका के साथ स्वयं निर्देशिका में रहते हैं, इसलिए मैं उस लूप ASAP को तोड़ना चाहता हूं।पायथन वॉक, लेकिन थ्रेड लाइटली

इतनी लंबी कहानी छोटी है, अगर पाइथन फाइल से मेल खाता है ".DPX $" यह उप-निर्देशिका सूचीबद्ध करता है, बैक आउट करता है, उस उप-निर्देशिका को छोड़ देता है और अन्य उप-निर्देशिकाओं में चलना जारी रखता है।

क्या सभी सूची परिणाम लौटाए जाने से पहले निर्देशिका सूची लूप तोड़ना संभव है?

+0

क्या डीपीएक्स छवि अनुक्रम वाले निर्देशिका नामों के बारे में कुछ अलग है? –

+0

यदि आप बड़ी निर्देशिकाओं को क्रमशः पढ़ना चाहते हैं (यानी न केवल रिकर्सन को रोकें, बल्कि उनकी व्यक्तिगत सामग्री भी न पढ़ें), तो आपको http: // stackoverflow पर वर्णित समाधानों की तरह कुछ उपयोग करने की आवश्यकता हो सकती है।कॉम/प्रश्न/44035 9 8/सूची-फाइल-इन-ए-फ़ोल्डर-ए-स्ट्रीम-टू-स्टार्ट-प्रोसेस-तत्काल –

+0

कुछ निर्देशिकाओं में नाम में 'डीपीएक्स' है, लेकिन उनमें से सभी नहीं :(@charles, क्या वह उदाहरण मेरे लिए काम करेगा। अगर मैं एक डीपीएक्स पार करता हूं तो मैं एक सूची से बाहर निकलना चाहता हूं, इस तरह से मैं 100,000 फ़ाइल नामों के माध्यम से पुनरावृत्ति से बच सकता हूं, जो काफी समय लेता है। – Jamie

उत्तर

1

os.listdir का उपयोग कर नामों की सूची आवंटित करने से बचने का सही तरीका ओएस स्तर के फ़ंक्शन का उपयोग करना है क्योंकि @ चार्ल्स डफी ने कहा।

यह अन्य पद से प्रेरित होकर: List files in a folder as a stream to begin process immediately

मैं विशिष्ट ओपी सवाल हल करने के लिए कैसे जोड़ा जाता है और समारोह की फिर से प्रवेशी संस्करण का उपयोग किया।

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 
+0

तो के बजाय "अगर idx> = max_per_dir:" इसके साथ प्रतिस्थापित करें: "अगर re.search ('\। DPX $', प्रविष्टि):" क्या यह इतना आसान है? – Jamie

+0

हाँ यदि आपको एक फ़ाइल मिलती है जो .DPX के साथ समाप्त होती है तो आप उस निर्देशिका को अनदेखा कर सकते हैं। लेकिन समारोह रिकर्सिव नहीं है, यह केवल एक ही पथ पर फिर से शुरू होगा। – fabrizioM

4

यदि 'निर्देशिका सूची लूप' से आपका मतलब os.listdir() है तो नहीं। इसे तोड़ा नहीं जा सकता है। हालांकि आप os.path.walk() या os.walk() विधियों को देख सकते हैं और केवल उन सभी निर्देशिकाओं को हटा सकते हैं जिनमें DPX फ़ाइलें हैं। यदि आप os.walk() का उपयोग करते हैं और ऊपर-नीचे चल रहे हैं तो आप निर्देशिकाओं की सूची को संशोधित करके पाइथन चलने वाली चीज़ों को प्रभावित कर सकते हैं। os.path.walk() आपको यह चुनने की अनुमति देता है कि आप यात्रा विधि के साथ कहां चलते हैं।

+1

विशेष रूप से - 'os.listdir() '(यानी अंतर्निहित सिस्टम कॉल का आह्वान करने के लिए' ctypes' का उपयोग करके) विकल्प हैं। _can_ –

+0

निर्देशिका में प्रत्येक फ़ाइल को पढ़ने से बचने के दौरान निर्देशिका में एक डीपीएक्स फ़ाइल है, तो मुझे कैसे पता चलेगा। इसमें डीपीएक्स के साथ निर्देशिकाओं को सूचीबद्ध करने में 30 मिनट लगते हैं। 'उदाहरण के लिए: ROOT_DIR /: -file.txt -subdir1/ --file1.txt --file2.txt --file3.txt -subdir2/ --file1.txt --file2.dpx ** * BREAK लूप *** --subdir3/ --file1.txt --file2.txt --file3.txt '' – Jamie

+0

ctypes' और निर्देशिका के फिर से प्रवेशी पढ़ने का प्रयोग शायद के रूप में आपका सर्वश्रेष्ठ दांव हैं @ चार्ल्स ने कहा। या आप एक विशेषज्ञ निर्देशिका लिस्टिंग फ़ंक्शन को सी पायथन मॉड्यूल के रूप में लिखने और इसे आयात करने पर विचार कर सकते हैं। सी में पुन: प्रवेश सूची का कुछ रूप, एक डीपीएक्स फ़ाइल मिलने पर अपवाद उठाते हुए, मॉड्यूल के रूप में आयात किया जाने वाला सबसे तेज़ समाधान होगा हालांकि पाइथन केवल समाधान से संभावित रूप से अधिक जटिल होगा। संभावित रूप से हालांकि नहीं। – Will

2
के अनुसार

documentationos.walk के लिए:

जब ऊपर से नीचेTrue है, फोन करने वाले dirnames संशोधित कर सकते हैं सूची में जगह , और walk() (जैसे, del या टुकड़ा काम के माध्यम से) होगा केवल उपनिर्देशिकाओं में भर्ती करें जिनके नाम dirnames में रहते हैं; इसका उपयोग खोज को छीनने के लिए किया जा सकता है, या विज़िट करने का एक विशिष्ट आदेश लागू करने के लिए किया जा सकता है। संशोधित करना dirnames जब ऊपर से नीचेFalse, अप्रभावी है के बाद से dirnames में निर्देशिका पहले से ही समय dirnames ही उत्पन्न होता है द्वारा उत्पन्न किया गया है।

तो सिद्धांत रूप में अगर आप खाली dirnames तो os.walk किसी भी अतिरिक्त निर्देशिका नीचे recurse नहीं होंगे। "... डेल या स्लाइस असाइनमेंट के माध्यम से" के बारे में टिप्पणी पर ध्यान दें; आप बस dirnames=[] नहीं कर सकते क्योंकि यह वास्तव में dirnames सूची की सामग्री को प्रभावित नहीं करेगा।

संबंधित मुद्दे