2012-12-13 16 views
6

क्या पाइथन में इसके लिए कोई अंतर्निहित कार्यक्षमता है? मेरा विचार यह है कि अगर किसी फ़ाइल को किसी निर्देशिका में आउटपुट किया जाता है तो यह कुछ ओएस के काम के तरीके से काम करेगा, जहां उस नाम की एक फ़ाइल पहले से मौजूद है। I.e: अगर "file.pdf" मौजूद है तो यह "file2.pdf" और अगली बार "file3.pdf" बनाएगा।पायथन: फ़ाइल बनाएं लेकिन यदि नाम मौजूद है तो

+0

यह आम तौर पर आवेदन या फ़ाइलों को इतना बनाने कार्यक्रम के समारोह होगा पूरा जब तक कि कोई है, वहाँ कोई देशी कार्यक्षमता इस तरह है । निर्देशिका और फ़ाइल नाम को देखते हुए आप स्वयं कुछ बना सकते हैं। – timc

+1

इसे जांचें http://code.activestate.com/recipes/578116-move-files-with-rename-if-required/ – avasal

+0

चेक करें ['filename_fix_existing (फ़ाइल नाम)'] (https://github.com/steveeJ /python-wget/blob/master/wget.py#L72) –

उत्तर

7

एक तरह से, पायथन ने यह कार्यक्षमता tempfile मॉड्यूल में बनाई है। दुर्भाग्य से, आपको एक निजी वैश्विक चर, tempfile._name_sequence में टैप करना होगा। इसका मतलब है कि आधिकारिक तौर पर, tempfile कोई गारंटी नहीं देता है कि भविष्य के संस्करणों में _name_sequence भी मौजूद है - यह एक कार्यान्वयन विवरण है। लेकिन अगर आप किसी तरह इसे उपयोग करने के साथ ठीक कर रहे हैं, यह दिखाता है कि आप एक निर्दिष्ट निर्देशिका में प्रपत्र file#.pdf की विशिष्ट नामित फ़ाइलें बना सकते हैं इस तरह के /tmp के रूप में:

import tempfile 
import itertools as IT 
import os 

def uniquify(path, sep = ''): 
    def name_sequence(): 
     count = IT.count() 
     yield '' 
     while True: 
      yield '{s}{n:d}'.format(s = sep, n = next(count)) 
    orig = tempfile._name_sequence 
    with tempfile._once_lock: 
     tempfile._name_sequence = name_sequence() 
     path = os.path.normpath(path) 
     dirname, basename = os.path.split(path) 
     filename, ext = os.path.splitext(basename) 
     fd, filename = tempfile.mkstemp(dir = dirname, prefix = filename, suffix = ext) 
     tempfile._name_sequence = orig 
    return filename 

print(uniquify('/tmp/file.pdf')) 
+0

उत्तर के लिए धन्यवाद! डॉक्स से पता लगाने के लिए मुश्किल सामान;) मैं अपना खुद का, सरल, दृष्टिकोण का चयन कर रहा हूं लेकिन यह उत्तर स्पष्ट रूप से उत्तर देता है कि मैं क्या सोच रहा था – Parham

+0

हां, शायद यह एक बुद्धिमान विकल्प है यदि आपको 'tempfile की विशेष क्षमताओं की आवश्यकता नहीं है '। 'Tempfile' मॉड्यूल कुछ दौड़ की स्थिति, सुरक्षा, और सेवा हमलों से इनकार करने से बचने के लिए दर्द होता है। अनुक्रमिक क्रमांकन का उपयोग उपर्युक्त कोड सेवा हमले से इनकार करने के लिए कमजोर बनाता है।और मुझे पूरी तरह से यकीन नहीं है कि ऊपर की दौड़ की स्थिति या अन्य सुरक्षा जोखिमों से सुरक्षित है। – unutbu

1

मैं अपने प्रोजेक्ट में एक ही बात को लागू करने की कोशिश कर रहा था लेकिन @ unutbu का जवाब लग रहा था मेरी जरूरतों के लिए भी 'भारी' तो मैं कोड अंत में निम्नलिखित के साथ आया था:

import os 
index = '' 
while True: 
    try: 
     os.makedirs('../hi'+index) 
     break 
    except WindowsError: 
     if index: 
      index = '('+str(int(index[1:-1])+1)+')' # Append 1 to number in brackets 
     else: 
      index = '(1)' 
     pass # Go and try create file again 

शायद ज़रुरत पड़े कोई इस पर ठोकर खाई और कुछ सरल की आवश्यकता है।

0

tempfile हैक ए के बाद से) एक हैक और बी) फिर भी कोड की एक सभ्य राशि की आवश्यकता है, मैं मैन्युअल कार्यान्वयन के साथ चला गया। आपको मूल रूप से आवश्यकता है:

  1. Safely create a file if and only if it does not exist का एक तरीका (यह है कि tempfile हैक हमें प्रदान करता है)।
  2. फ़ाइल नामों के लिए जनरेटर।
  3. गड़बड़ को छिपाने के लिए एक रैपिंग फ़ंक्शन।

मैं एक safe_open कि अभी खुला तरह इस्तेमाल किया जा सकता परिभाषित:

def iter_incrementing_file_names(path): 
    """ 
    Iterate incrementing file names. Start with path and add " (n)" before the 
    extension, where n starts at 1 and increases. 

    :param path: Some path 
    :return: An iterator. 
    """ 
    yield path 
    prefix, ext = os.path.splitext(path) 
    for i in itertools.count(start=1, step=1): 
     yield prefix + ' ({0})'.format(i) + ext 


def safe_open(path, mode): 
    """ 
    Open path, but if it already exists, add " (n)" before the extension, 
    where n is the first number found such that the file does not already 
    exist. 

    Returns an open file handle. Make sure to close! 

    :param path: Some file name. 

    :return: Open file handle... be sure to close! 
    """ 
    flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY 

    if 'b' in mode and platform.system() == 'Windows': 
     flags |= os.O_BINARY 

    for filename in iter_incrementing_file_names(path): 
     try: 
      file_handle = os.open(filename, flags) 
     except OSError as e: 
      if e.errno == errno.EEXIST: 
       pass 
      else: 
       raise 
     else: 
      return os.fdopen(file_handle, mode) 

# Example 
with safe_open("some_file.txt", "w") as fh: 
    print("Hello", file=fh) 
0

मैं अभी तक इस परीक्षण नहीं किया है, लेकिन यह काम करना चाहिए, सवाल पर मौजूद नहीं है में फ़ाइल जब तक संभव फ़ाइल नाम से अधिक पुनरावृत्ति जो बिंदु टूटता है।

def increment_filename(fn): 
    fn, extension = os.path.splitext(path) 

    n = 1 
    yield fn + extension 
    for n in itertools.count(start=1, step=1) 
     yield '%s%d.%s' % (fn, n, extension) 

for filename in increment_filename(original_filename): 
    if not os.isfile(filename): 
     break 
0

हाल ही में मैं एक ही बात हुई है और उसे यहां मेरे दृष्टिकोण है:

import os 

file_name = "file_name.txt" 
if os.path.isfile(file_name): 
    expand = 1 
    while True: 
     expand += 1 
     new_file_name = file_name.split(".txt")[0] + str(expand) + ".txt" 
     if os.path.isfile(new_file_name): 
      continue 
     else: 
      file_name = new_file_name 
      break 
0

यह मेरे लिए काम करता है। प्रारंभिक फ़ाइल नाम 0.yml है, यदि वह मौजूद है, यह एक जोड़ देगा आवश्यकता

import os 
import itertools 

def increment_filename(file_name): 
    fid, extension = os.path.splitext(file_name) 

    yield fid + extension 
    for n in itertools.count(start=1, step=1): 
     new_id = int(fid) + n 
     yield "%s%s" % (new_id, extension) 


def get_file_path(): 
    target_file_path = None 
    for file_name in increment_filename("0.yml"): 
     file_path = os.path.join('/tmp', file_name) 
     if not os.path.isfile(file_path): 
      target_file_path = file_path 
      break 
    return target_file_path 
संबंधित मुद्दे