Veränderung einer File im ZIP-Vereichnis in place

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
fuppes
User
Beiträge: 28
Registriert: Dienstag 15. April 2008, 22:33

Hallo,

ist es möglich eine Datei die sich in einem Zip Verzeichnis befindet direkt zu verändert, ohne diese datei erst zu entpacken und dann wieder in das Verzeichnis zu schreiben?
Also mein zip Verzeichnis beinhalte ein anders zip verzeichnis in dem eine txt datei steht die ich verändern möchte.

Gibts da was feines?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Schau dir mal zipfile an.
fuppes
User
Beiträge: 28
Registriert: Dienstag 15. April 2008, 22:33

hi,

ja hab ich gemacht, aber so wie ich das verstanden habe kann ich (mit zipfile) nur neue datei an das Verzeichnis anhängen, ich möchte aber eine Datei die bereits in dem Verzchnis ist, verändern.
OverNord
User
Beiträge: 72
Registriert: Donnerstag 24. Januar 2008, 11:59
Kontaktdaten:

Hohl doch einfach die zu verändernde Datei aus dem Archiv, ändere sie und packe sie wieder in das Archiv. Ich kenne mich leider nicht sonderlich gut mit zipfile aus, benutzte tarfile, aber die sollten eigentlich recht ähnlich arbeiten und bei tarfile ist das oben geschriebene möglich.
fuppes
User
Beiträge: 28
Registriert: Dienstag 15. April 2008, 22:33

also irgendwie bekomme ich das net hin....

Hier mal mein code:

Code: Alles auswählen

# -*- coding: cp1252 -*-

import StringIO
import gzip
import zipfile
import tempfile
import os

def update_mani(mani_as_string):
    tmp_url = r'C:\tmp\mani_tmp.txt'
    
    # create file object:
    #file_obj = open(tmp_url, 'w')
    #file_obj.write('fupp' * 1000)
    #file_obj.close()

    return r'C:\tmp\IMG_0962.jpg'

def main(f_url):
    try:
        zip_f = zipfile.ZipFile(f_url, 'r')
        content = zip_f.namelist()

        war_filter = lambda x: True if x.lower().endswith('war') else False
        war_list = filter(war_filter, content)
        
        for war in war_list:
            print '>>>', war
            
            file_like = StringIO.StringIO(zip_f.read(war))
            war_zip = zipfile.ZipFile(file_like, 'r')
            war_content = war_zip.namelist()

            print '-->', len(war_content)
           
           
            for item in war_content:
                if item.upper().endswith('MANIFEST.MF'):
                    mani_content = war_zip.read(item)
                
                    tag = 'Class-Path'
                    if tag.lower() in mani_content.lower():
                        #print 'found class path manifest:'
                        #print mani_content
                         
                        tmp_url = update_mani(mani_content)

                        # print tmp_url
            
                        war_zip_w = zipfile.ZipFile(file_like, 'a')
                        war_zip_w.write(tmp_url)
                        war_zip_w.close()

                        # testing
                        war_zip_w = zipfile.ZipFile(file_like, 'r')
                        war_content = war_zip_w.namelist()
                        
                        print '-->', len(war_content)
                        
                        for con in war_content:
                            if con.endswith('IMG_0962.jpg'):
                                print con

    except Exception, e:
        print e
    finally:
        zip_f.close()



if __name__ == '__main__':
    f_dir = r'C:\'
    f_name = 'ear-4.6.8.2.ear'
    f_url = os.path.join(f_dir, f_name)
    main(f_url)
Also wenn ich mir hier zweimal len ausgeben lasse unterscheind sich die beiden zip files (len(war_content)). Aber wenn ich dann in mein Zip Verzeichnis schau hat sich nix getan....
Bin mir auch nicht sicher ob ich das ueberhaupt richtig machen mit dem zugriff auf das zweite verzeichnis. Alos in dem ersten xy.ear befindenden sich mehrer andere gepackte verzeichnisse (xy.war). und in diesen .war muss ich jeweils die Manifest.MF verändert.

so jetzt ich es echts schon sau spät, vielleicht fällt mir morgen was ein.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Das ist sicher nicht exakt dein Code...
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
fuppes
User
Beiträge: 28
Registriert: Dienstag 15. April 2008, 22:33

guten morgen,

was meinst du? bis auf f_dir hab ich nix geändert.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Genau: das neue f_dir verursacht einen SyntaxError.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
fuppes
User
Beiträge: 28
Registriert: Dienstag 15. April 2008, 22:33

ups, wohl doch etwas viel von der url weggenommen. Aber selbst mit

Code: Alles auswählen

f_dir = r'C:\\'
bleibt ja leider mein ursprüngliches problem bestehen. [/code]
fuppes
User
Beiträge: 28
Registriert: Dienstag 15. April 2008, 22:33

hallo,

also ich hab mich da jetzt nochmal drann gemacht, es gibt wohl keine methode eine file im zip direkt zu verändern, folglich muss ich wohl alles entpacken (auch die zipfile im toplevel zip) die entsprechenden datei ändern und dann wieder alles zippen.

Also ich habe die beiden methode fertig und die machen auch was sie sollen, aber ich wollte jetzt mal eure meinung hören, also ob die methoden was nützen oder nicht (was wohl das wahrscheinlichste ist ;) )

Code: Alles auswählen

def remove_dirTree(dir_url):
    command = r'rmdir /S /Q %s'
    command = command%dir_url

    if os.path.isdir(dir_url):
        os.system(command)

        
def package_war(wars_root, target_url):
    postfix = '.war'
    warlist = os.listdir(wars_root)

    for war in warlist:
        print 'war: ', war
        war_name = '%s%s'%(war, postfix)
        
        new_war_zf = zipfile.ZipFile(os.path.join(target_url, war_name ),
                                     'w',
                                     compression = zipfile.ZIP_DEFLATED)

        for content in os.walk(os.path.join(wars_root, war)):
            # print content
            # raw_input()
            
            for item in content[2]:
                arcname = content[0][len(os.path.join(wars_root, war))+1:]
                if len(arcname) == 0:
                    arcname = item
                else:
                    arcname = '%s\\%s'%(arcname, item)
                    
                #print 'arcname: ', arcname
                #raw_input('>>')
                new_war_zf.write(os.path.join(content[0], item ), arcname)

        new_war_zf.close()
        
    # delete the director:
    remove_dirTree(wars_root)
        
        
def package_ear( f_url, filename , target_url):
    postfix = '.ear'
    if not filename.lower().endswith(postfix.lower()):
        ear_name = '%s%s'%(filename, postfix)
    else:
        ear_name = filename
        
    # delete the old elements in the target dir:
    filelist = os.listdir( target_url )
    for old_file in filelist:
        if os.path.isfile(os.path.join(target_url, old_file)):
            os.remove(os.path.join(target_url, old_file))
    
    # package the wars:    
    itemlist = os.listdir(f_url)
    if 'wars' in [x.lower() for x in itemlist]:
        package_war(os.path.join(f_url, 'wars'), target_url)
        
    # start packaging the EAR:    
    new_zf = zipfile.ZipFile( os.path.join(target_url, ear_name),
                              'w',
                              compression = zipfile.ZIP_DEFLATED)

    filelist = os.listdir( target_url )

    # add war to the EAR
    for item in filelist:
        print 'ear item: ', item
        if os.path.isfile(os.path.join( target_url, item )):
            if item != ear_name:
                new_zf.write(os.path.join( target_url, item ), item)
                os.remove(os.path.join( target_url, item ))

    # add the other files to the EAR
    for content in os.walk(f_url):
        for item in content[2]:
            arcname = content[0][len(f_url)+1:]
            if len(arcname) == 0:
                arcname = item
            else:
                arcname = '%s\\%s'%(arcname, item)
                    
            # print 'arcname: ', arcname
            new_zf.write(os.path.join(content[0], item), arcname)    
    new_zf.close()

    
def extract( filename, target_dir ):
    # see: http://code.activestate.com/recipes/465649/
    zf = zipfile.ZipFile( filename )
    namelist = zf.namelist()
    dirlist = filter( lambda x: x.endswith( '/' ), namelist )
    filelist = filter( lambda x: not x.endswith( '/' ), namelist )
    
    # make base
    pushd = os.getcwd()
    if not os.path.isdir( target_dir ):
        os.mkdir( target_dir )
    os.chdir( target_dir )
    
    # create directory structure
    dirlist.sort()
    for dirs in dirlist:
        dirs = dirs.split( '/' )
        prefix = ''
        for dir in dirs:
            dirname = os.path.join( prefix, dir )
            if dir and not os.path.isdir( dirname ):
                os.mkdir( dirname )
            prefix = dirname
            
    # extract files
    for fn in filelist:            
        try:
            out = open( fn, 'wb' )
            buffer = StringIO( zf.read( fn ))
            buflen = 2 ** 20
            content = buffer.read( buflen )
            while content:
                out.write( content )
                content = buffer.read( buflen )
            out.close()

            if fn.lower().endswith('.war'):
                # recursive --> extract wars:
                war_sub_folder = 'WARS'
                if not os.path.isdir(os.path.join(os.getcwd(), war_sub_folder)):
                    os.mkdir( os.path.join(os.getcwd(), war_sub_folder) )
                    
                war_url = os.path.join(os.getcwd(), fn)
                war_target = os.path.join(os.getcwd(),
                                          war_sub_folder,
                                          os.path.basename(fn)[:-4])
                
                extract(war_url, war_target)

                # delete the .wars:
                os.remove(war_url)
                
        except Exception, e:
            print e
        finally:
            pass
            #print fn
    os.chdir( pushd )
Wäre nett wenn mein paar von euch was dazu sagen könnten. danke
Antworten