Je me retrouve de plus en plus à SO récemment. Tout en essayant d'apprendre Python (en sautant à droite et en essayant de porter une application à partir de C#), j'ai découvert quelque chose dont je n'avais jamais entendu parler auparavant: Threading. Quand j'ai pensé que j'avais une compréhension basique, j'ai essayé de convertir la partie du programme qui zippe un répertoire plein de fichiers (et sous-répertoires). C'est ce que je suis venu avec à ce jour - avec l'aide de quelques sources que je vais énumérer à la fin:Filetage Python zipfile à utiliser avec barre de progression
from Queue import Queue
import os
import gtk
import threading
import time
import zipfile
debug = True
class ProduceToQueue(threading.Thread):
def __init__(self, threadName, queue, window, maximum, zipobj, dirPath):
threading.Thread.__init__(self, name = threadName)
self.sharedObject = queue
self.maximum = maximum
self.zip = zipobj
self.dirPath = dirPath
self.window = window
global debug
if debug:
print self.getName(), "got all params."
def run(self):
if debug:
print "Beginning zip."
files = 0
parentDir, dirToZip = os.path.split(self.dirPath)
includeDirInZip = False
#Little nested function to prepare the proper archive path
def trimPath(path):
archivePath = path.replace(parentDir, "", 1)
if parentDir:
archivePath = archivePath.replace(os.path.sep, "", 1)
if not includeDirInZip:
archivePath = archivePath.replace(dirToZip + os.path.sep, "", 1)
return os.path.normcase(archivePath)
for (archiveDirPath, dirNames, fileNames) in os.walk(self.dirPath):
#if debug:
#print "Walking path..."
for fileName in fileNames:
time.sleep(0.001)
#if debug:
#print "After a small sleep, I'll start zipping."
filePath = os.path.join(archiveDirPath, fileName)
self.zip.write(filePath, trimPath(filePath))
#if debug:
#print "File zipped - ",
files = files + 1
#if debug:
#print "I now have ", files, " files in the zip."
self.sharedObject.put(files)
#Make sure we get empty directories as well
if not fileNames and not dirNames:
zipInfo = zipfile.ZipInfo(trimPath(archiveDirPath) + "/")
#some web sites suggest doing
#zipInfo.external_attr = 16
#or
#zipInfo.external_attr = 48
#Here to allow for inserting an empty directory. Still TBD/TODO.
outFile.writestr(zipInfo, "")
class ConsumeFromQueue(threading.Thread):
def __init__(self, threadName, queue, window, maximum):
threading.Thread.__init__(self, name = threadName)
self.sharedObject = queue
self.maximum = maximum
self.window = window
global debug
if debug:
print self.getName(), "got all params."
def run(self):
print "Beginning progress bar update."
for i in range(self.maximum):
time.sleep(0.001)
#if debug:
#print "After a small sleep, I'll get cracking on those numbers."
current = self.sharedObject.get()
fraction = current/float(self.maximum)
self.window.progress_bar.set_fraction(fraction)
#if debug:
#print "Progress bar updated."
class MainWindow(gtk.Window):
def __init__(self):
super(MainWindow, self).__init__()
self.connect("destroy", gtk.main_quit)
vb = gtk.VBox()
self.add(vb)
self.progress_bar = gtk.ProgressBar()
vb.pack_start(self.progress_bar)
b = gtk.Button(stock=gtk.STOCK_OK)
vb.pack_start(b)
b.connect('clicked', self.on_button_clicked)
b2 = gtk.Button(stock=gtk.STOCK_CLOSE)
vb.pack_start(b2)
b2.connect('clicked', self.on_close_clicked)
self.show_all()
global debug
def on_button_clicked(self, button):
folder_to_zip = "/home/user/folder/with/lotsoffiles"
file_count = sum((len(f) + len(d) for _, d, f in os.walk(folder_to_zip)))
outFile = zipfile.ZipFile("/home/user/multithreadziptest.zip", "w", compression=zipfile.ZIP_DEFLATED)
queue = Queue()
producer = ProduceToQueue("Zipper", queue, self, file_count, outFile, folder_to_zip)
consumer = ConsumeFromQueue("ProgressBar", queue, self, file_count)
producer.start()
consumer.start()
producer.join()
consumer.join()
outFile.close()
if debug:
print "Done!"
def on_close_clicked(self, widget):
gtk.main_quit()
w = MainWindow()
gtk.main()
problème est au bout d'environ 7000 fichiers les écluses du programme et je dois forcer le quitter . Je n'ai pas essayé avec moins de fichiers que ça, mais je pense que ça aurait probablement le même problème. En outre, la barre de progression ne se met pas à jour. Je sais que c'est désordonné (programmation style sage avec mixte underscored et CamelCase, et les erreurs noobish générales), mais je ne peux pas penser à aucune raison pour que cela ne fonctionne pas.
est ici où je suis le plus de ceci:
http://www.java2s.com/Code/Python/File/Multithreadingzipfile.htm http://www.java2s.com/Tutorial/Python/0340__Thread/Multiplethreadsproducingconsumingvalues.htm
'> par exemple lorsque vous utilisez GTK vous ne voulez pas du tout vos propres threads.' Qu'entendez-vous par là? Tous les autres tutoriels que j'ai vu sur le filetage avec GTK le font comme ça. – Micheal
@Mike: Voir edit –
Merci, je vais jeter un oeil et voir si je ne peux pas comprendre cette chose. – Micheal