2016-04-07 16 views
1

Almanca isimleri dosya adlarında değiştiren bir komut dosyası çalıştırıyorum. Bunu yapmak için ihtiyacım olan 1700'den fazla dosya var, ancak komut dosyası bir süre çalıştıktan sonra çok fazla açık dosya olduğunu belirten bir hata alıyorum. Bunu düzeltmek için herhangi bir fikri olan var mı? Geribildirim büyük takdir!Windows üzerinde Python 2.7 - Çok Fazla Açık Dosya

Kodu:

# -*- coding: utf-8 -*- 

''' Script replaces all umlauts in filenames within a root directory and its subdirectories with the English 
    equivalent (ie. ä replaced with ae, Ä replaced with Ae).''' 

import os 
import itertools 
import logging 
from itertools import groupby 

##workspace = u'G:\\Dvkoord\\GIS\\TEMP\\Tle\\Scripts\\Umlaut' 
workspace = u'G:\\Gis\\DATEN' 
log = 'Umlauts.log' 
logPath = r"G:\Dvkoord\GIS\TEMP\Tle\Scripts\Umlaut\Umlauts.log" 
logMessageFormat = '%(asctime)s - %(levelname)s - %(message)s' 


def GetFilepaths(directory): 
    """Function returns a list of file paths in a directory tree using os.walk. Parameter: directory 
    """ 
    file_paths = [] 
    for root, directories, files in os.walk(directory): 
     for filename in files: 
      filepath = os.path.join(root, filename) 
      file_paths.append(filepath) 
## file_paths = list(set(file_paths)) 
    return file_paths 

def uniq(input): 
    output = [] 
    for x in input: 
    if x not in output: 
     output.append(x) 
    return output 

def Logging(logFile, logLevel, destination, textFormat, comment): 
    """Function writes a log file. Parameters: logFile (name the log file w/extension), 
     logLevel (DEBUG, INFO, etc.), destination (path under which the log file will be 
     saved including name and extension), textFormat (how the log text will be formatted) 
     and comment. 
    """ 
    # logging 
    logger = logging.getLogger(__name__) 
    # set log level 
    logger.setLevel(logLevel) 
    # create a file handler for the log -- unless a separate path is specified, it will output to the directory where this script is stored 
    logging.FileHandler(logFile) 
    handler = logging.FileHandler(destination) 
    handler.setLevel(logLevel) 
    # create a logging format 
    formatter = logging.Formatter(textFormat) 
    handler.setFormatter(formatter) 
    # add the handlers to the logger 
    logger.addHandler(handler) 
    logger.info(comment) 


def main(): 
    # dictionary of umlaut unicode representations (keys) and their replacements (values) 
    umlautDictionary = { 
         u'Ä': 'Ae', 
         u'Ö': 'Oe', 
         u'Ü': 'Ue', 
         u'ä': 'ae', 
         u'ö': 'oe', 
         u'ü': 'ue', 
         u'ß': 'ss' 
         } 
    dataTypes = [".CPG", 
       ".dbf", 
       ".prj", 
       ".sbn", 
       ".sbx", 
       ".shp", 
       ".shx", 
       ".shp.xml", 
       ".lyr"] 
    # get file paths in root directory and subfolders 
    filePathsList = GetFilepaths(workspace) 
    # put all filepaths with an umlaut in filePathsUmlaut list 
    filePathsUmlaut = [] 
    for fileName in filePathsList: 
##  print fileName 
     for umlaut in umlautDictionary: 
      if umlaut in os.path.basename(fileName): 
       for dataType in dataTypes: 
        if dataType in fileName: 
##      print fileName 
         filePathsUmlaut.append(fileName) 
    # remove duplicate paths from filePathsUmlaut 
    uniquesUmlauts = uniq(filePathsUmlaut) 

    # create a dictionary for umlaut translation 
    umap = { 
      ord(key):unicode(val) 
      for key, val in umlautDictionary.items() 
      } 
    # use translate and umap dictionary to replace umlauts in file name and put them in the newFilePaths list 
    # without changing any of the umlauts in folder names or upper directories 
    newFilePaths = [] 
    for fileName in uniquesUmlauts: 
     pardir = os.path.dirname(fileName) 
     baseName = os.path.basename(fileName) 
     newBaseFileName = baseName.translate(umap) 
     newPath = os.path.join(pardir, newBaseFileName) 
     newFilePaths.append(newPath) 
    newFilePaths = uniq(newFilePaths) 

    # create a dictionary with the old umlaut path as key and new non-umlaut path as value 
    dictionaryOldNew = dict(itertools.izip(uniquesUmlauts, newFilePaths)) 
    # rename old file (key) as new file (value) 
    for files in uniquesUmlauts: 
     for key, value in dictionaryOldNew.iteritems(): 

      if key == files: 
       comment = '%s'%files + ' wurde als ' '%s'%value + ' umbenannt.' 
       print comment 
       if os.path.exists(value): 
        os.remove(value) 
       os.rename(files, value) 
       Logging(log, logging.INFO, logPath, logMessageFormat, comment) 


if __name__ == '__main__': 
    main() 
+0

Hataları iletebilir misiniz? – qvpham

+1

Her döngüde bir günlük işleyici oluşturuyor musunuz? –

+0

@padraic - Evet, ShadowRanger bunun altını çizdi, muhtemelen sorun bu. günlüğe kaydetmeden onu deneyecek ve neyin sarsıldığını göreceksiniz. –

cevap

4

Ben sorun Logging işlevi olduğunu düşünüyorum. Her oturum açtığınızda, yeni bir FileHandler oluşturuyorsunuz ve bunu işleyicilerin grubuna ekliyorsunuz ve bunu yeniden adlandırılan her dosya için yapıyorsunuz, böylece açık dosya tanımlayıcıları üzerindeki sınırı hızla vurursunuz. Kaydedicinizi bir kez yapılandırın, sonra birçok kez kullanın, her kullandığınızda yapılandırmayın.

Kural dışı durumun Logging; Windows'ta bir dosyayı silmek, silme için açmayı içerir, böylece açık dosyaları kayıt defterleriyle maksimuma çıkarabilir, daha sonra bir dosyayı silmeye çalıştığınızda başarısız olursunuz.

+0

ah - bu mantıklı, teşekkürler. Günlüğe kaydetmeden bir dönüş yapacağım ve ne olduğunu göreceğim. –

+0

Bu yüzden, logger'ı bir kez yapılandırmak için en iyi yol (koduma dayanarak), sonra şu anda yaptığımın aksine, onu defalarca kullanabilirim? –

+0

@CrazyOtto: Sadece bir işlevde değil, global olarak 'logger' öğesini en üst düzeyde oluşturun ve yapılandırın ve 'logging.info (comment) 'ile aramaları' Logging' olarak değiştirin. – ShadowRanger

İlgili konular