2010-12-05 4 views
0

最近、私は自分自身がますます近づいてきていると感じています。 Pythonを習得しようとしているうちに(C#からアプリケーションを移植する)、以前は聞いたことのないものが出てきました。私は基本的な理解があったと思ったとき、ファイル(とサブディレクトリ)でいっぱいのディレクトリを圧縮するプログラムの部分を変換しようとしました。これは私がこれまでに思い付いたものです - 私は最後にリストアップしますいくつかのソースからの助けを借りて約7,000アッププログラムのロックをファイルし、私はそれを強制終了した後、これとプログレスバーで使用するためのPython zipfileスレッド化

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() 

問題があります。それより少ないファイルで試したことはありませんが、おそらく同じ問題があると思います。また、進行状況バーは更新されません。私はそれが乱雑であることを知っています(混合したアンダースコアとキャメルケース、そして一般的なノービックミスによるスタイルのプログラミング)が、それはうまくいかない理由は考えられません。

http://www.java2s.com/Code/Python/File/Multithreadingzipfile.htm http://www.java2s.com/Tutorial/Python/0340__Thread/Multiplethreadsproducingconsumingvalues.htm

答えて

0

私はfile_countが間違っていると消費者が.getに別のオブジェクトのために永遠に待つ推測すると思います:

は、ここで私はこれのほとんどを持っているのです。行をcurrent = self.sharedObject.get(timeout=5)に変更し、その場合は最後にエラーが発生するはずです。

また、はい、あなたのコードには多くの問題があります。たとえば、GTKを使用する場合は、スレッドをまったく必要としません。

GTKにはgtksメインループで使用するのに安全な独自のスレッドライブラリがあります。 http://www.pardon-sleeuwaegen.be/antoon/python/page0.htmlやgoogleの "gtk threading"のようなページを参照してください

+0

'GTKを使用すると、自分のスレッドをまったく必要としない場合など。 どういう意味ですか? GTKを使ったスレッディングで見た他のチュートリアルでは、このようにしています。 – Micheal

+0

@Mike:編集 –

+0

を参照してくださいありがとう、私は見て、私はこの事を把握することができないかどうかを確認します。 – Micheal

関連する問題