2016-07-25 14 views
1

Ich habe ein Problem mit der Verarbeitung von über 2700 Dateien Das funktioniert, wenn ich ein wenig von einer Datei wie ein paar hundert habe, und ich vermute, es hat mit Fenstern zu tun, die öffnen Dateien wie in Linux ulimit können systemweit definiert werden. Ich bin mir sicher, dass die Dinge nicht geschlossen werden und deshalb bekomme ich diesen Fehler.Zu viele offene Dateien urllib

Ich habe eine Funktion, die eine Datei per Post sendet:

def upload_photos(url_photo, dict, timeout): 
    photo = dict['photo'] 
    data_photo = dict['data'] 
    name = dict['name'] 
    conn = requests.post(url_photo, data=data_photo, files=photo, timeout=timeout) 
    return {'json': conn.json(), 'name': name} 

, die aus einer Schleife eines Verzeichnisliste aufgerufen:

for photo_path in [p.lower() for p in photos_path]: 
     if ('jpg' in photo_path or 'jpeg' in photo_path) and "thumb" not in photo_path: 
      nr_photos_upload +=1 
    print("Found " + str(nr_photos_upload) + " pictures to upload") 
    local_count = 0 
    list_to_upload = [] 
    for photo_path in [p.lower() for p in photos_path]: 
     local_count += 1 
     if ('jpg' in photo_path or 'jpeg' in photo_path) and "thumb" not in photo_path and local_count > count: 
      total_img = nr_photos_upload 
      photo_name = os.path.basename(photo_path) 
      try : 
       photo = {'photo': (photo_name, open(path + photo_path, 'rb'), 'image/jpeg')} 
       try: 
        latitude, longitude, compas = get_gps_lat_long_compass(path + photo_path) 
       except ValueError as e: 
        if e != None: 
         try: 
          tags = exifread.process_file(open(path + photo_path, 'rb')) 
          latitude, longitude = get_exif_location(tags) 
          compas = -1 
         except Exception: 
          continue 
       if compas == -1: 
        data_photo = {'coordinate' : str(latitude) + "," + str(longitude), 
           'sequenceId'  : id_sequence, 
           'sequenceIndex' : count 
           } 
       else : 
        data_photo = {'coordinate' : str(latitude) + "," + str(longitude), 
           'sequenceId'  : id_sequence, 
           'sequenceIndex' : count, 
           'headers'   : compas 
           } 
       info_to_upload = {'data': data_photo, 'photo':photo, 'name': photo_name} 
       list_to_upload.append(info_to_upload) 
       count += 1 
      except Exception as ex: 
       print(ex) 
    count_uploaded = 0 
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: 
     # Upload feature called from here 
     future_to_url = {executor.submit(upload_photos, url_photo, dict, 100): dict for dict in list_to_upload} 
     for future in concurrent.futures.as_completed(future_to_url): 
      try: 
       data = future.result()['json'] 
       name = future.result()['name'] 
       print("processing {}".format(name)) 
       if data['status']['apiCode'] == "600": 

        percentage = float((float(count_uploaded) * 100)/float(total_img)) 
        print(("Uploaded - " + str(count_uploaded) + ' of total :' + str(
         total_img) + ", percentage: " + str(round(percentage, 2)) + "%")) 
       elif data['status']['apiCode'] == "610": 
        print("skipping - a requirement arguments is missing for upload") 
       elif data['status']['apiCode'] == "611": 
        print("skipping - image does not have GPS location metadata") 
       elif data['status']['apiCode'] == "660": 
        print("skipping - duplicate image") 
       else : 
        print("skipping - bad image") 
       count_uploaded += 1 
       with open(path + "count_file.txt", "w") as fis: 
        fis.write((str(count_uploaded))) 
      except Exception as exc: 
       print('%generated an exception: %s' % (exc)) 
+0

Also, das Problem ist in simulatanious Verarbeitung zu viele Dateien. Vielleicht ist der einfachste Weg, um es zu beheben, folgt: nicht aufhören, wenn es ein Problem gibt, aber warten Sie einige Millisekunden und wiederholen Sie (achten Sie darauf, Endlosschleife zu vermeiden). In diesem Fall werden alle Dateien verarbeitet. – Ilya

+0

In häufigen Fällen ist es selten vorteilhaft, mehr als eine Handvoll Dateien gleichzeitig hochzuladen, besonders wenn Sie den gleichen Server hämmern. Verringern Sie die Anzahl der gleichzeitigen Verbindungen. –

Antwort

1

Sie _setmaxstdio in C einstellen können, um die Nummer zu ändern von Dateien, die gleichzeitig geöffnet werden können.

Für Python haben Sie win32file von pywin32 wie zu verwenden:

import win32file 
win32file._setmaxstdio(1024) #set max number of files to 1024 

Der Standard 512 ist. Und stellen Sie sicher, dass Sie überprüfen, ob der von Ihnen festgelegte Höchstwert von Ihrer Plattform unterstützt wird.

Referenz: https://msdn.microsoft.com/en-us/library/6e3b887c.aspx

+1

"maximale Anzahl von offenen Dateien" ist diese Art von Grenze, die heutzutage hoch genug ist, dass Sie Ihren Algorithmus in Frage stellen sollten, keine Möglichkeiten finden, das Limit zu ändern ... –

+1

Diese Option funktioniert nicht und was Matteo sagte, ist es nicht Best Practice, um so etwas zu tun – James

Verwandte Themen