Python實現簡單的打包

版權所有,轉載請註明出處:http://guangboo.org/2013/03/14/package-with-python-implement

通常我們在對目錄進行打包時都是有zip或rar工具,然而現在就遇到一個問題。我可以通過zip來對目錄進行打包,但是我沒有辦法將這樣一個文件上傳到服務器(內網受限),只能上傳圖標格式,或文本格式。由於我目錄下也都是文本文件,所有這裏就想到一個變通的辦法,將目錄層次結構和文件的內容都存到一個文本文件裏面,然後上傳。

文本文件的格式也只需要稍作規定,第一行爲“打包”目錄的根目錄,第二行開始爲目錄名字,文件名,然後是文件內容。格式如下啊:

source file root directory
>>> [direcotry1]
>>> [direcotry2]
>>> filename1
file content..................................................
......................................
>>> filename2
file content..................................................
......................................

這樣的格式,我們就可以對其解析,並還原到磁盤。那麼實現“打包”的過程,使用python來實現,如下:

# -*- coding:utf-8 -*-
import os
import sys
import codecs

def compress(src_dir, target_file):
      output = codecs.open(target_file, 'w', 'utf-8')
      # write root
      print >> output, src_dir
      
      for _dir, sub_dirs, files in os.walk(src_dir):
            for sub_dir in sub_dirs:
                  print >> output, u'\n>>> [%s%s%s]' % (_dir, os.sep, sub_dir)
                  print >> sys.stdout, u'>>> [%s%s%s]' % (_dir, os.sep, sub_dir)
            for filename in files:
                  if os.path.splitext(filename)[-1] in ['.txt', '.css', '.js', '.html', '.htm', '.py']:
                        src_file = '%s%s%s' % (_dir, os.sep, filename)
                        print >> sys.stdout, '>>> ', src_file
                        tf = codecs.open(src_file, 'r', 'utf-8')
                        print >> output, u'\n>>> %s' % src_file
                        for line in tf.readlines():
                              output.write(u'%s' % line)
      output.close()

代碼中使用codecs.open方法,主要是可以通過utf-8編碼方式來打開文件,並使用os.walk來遍歷跟目錄src_dir下所有子目錄和文件。那麼只需要簡單調用該方法,傳遞要“打包”的目錄地址,和要“打包”成的文件名即可,如:

compress('c:\\project', 'c:\\project.txt')

這樣“打包”過程,便完成了,但是有了打包過程,必定要有“解包”的過程,既然我們知道“打包”後的文件格式,那麼也就很容易將文件的內容重新還原到磁盤上,代碼如下:

def decompress(src_file, target_dir):
      import re
      input = open(src_file, 'r')
      root = input.readline()
      cut_len = len(root)
      line = input.readline()
      dir_reg = re.compile('\[(.+)\]')
      filename_reg = re.compile('^>>> (.+)$')
      target_file = None
      
      while line:
            if line.startswith('>>> ['):
                  if target_file:
                        target_file.close()
                        target_file = None
                  txt = dir_reg.findall(line)
                  if txt:
                        dir_handler(txt[0][cut_len:], target_dir)
            elif line.startswith('>>>'):
                  if target_file:
                        target_file.close()
                        target_file = None
                  txt = filename_reg.findall(line)
                  if txt:
                        fn = os.path.join(target_dir, txt[0][cut_len:])
                        target_file = open(fn, 'w')
                        print >> sys.stdout, 'file:%s' % fn
            elif target_file:
                  target_file.write(line)
                  
            line = input.readline()
            
      if target_file:
            target_file.close()
      input.close()

def dir_handler(txt, target_dir):
      _dir = os.path.join(target_dir, txt)
      try:
            os.mkdir(_dir)
            print >> sys.stdout, 'dir:%s' % _dir
      except IOError:
            print '>>> Directory %s created failed.' % _dir

該方法是用正則表達來判斷“包”文件的行,是目錄還是文件,或者是文件內容。並可以還原目錄結構。進行還原時,需要調用decompress方法,傳遞包文件名稱,和存放目錄。如:

decompress('c:\\project.txt', 'c:\\project2', )

那麼爲了方便,我們將兩個方法定義到同一文件zip.py中,並添加如下代碼,使得可以在命令行中傳遞參數,實現“打包”和“解包”功能:

if __name__ == '__main__':
      cmd = sys.argv[1]
      src = sys.argv[2]
      target = sys.argv[3]

      if cmd == 'compress':
            compress(src, target)
      elif cmd == 'decompress':
            decompress(src, target)

那麼“打包”和“解包”的過程,就可以通過如下命令來實現:

zip.py compress c:\project c:\package.txt

zip.py decompress c:\package.txt c:\project2

下載文件:zip.py

發佈了124 篇原創文章 · 獲贊 4 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章