Aufteilung eines zu großen Zipfile? Aber wie?

J

joekey

Grünschnabel
Hallo,

ich kann folgendes Problem nicht lösen: :hilfe2:

es sollen viele Dateien (bis zu 10 Gb) gezipped werden und anschließend die entstandene Zipfile/s (falls aufgeteilt) verschoben werden. Das Problem ist wie man das Zipfile beim erstellen teilt, bzw. steuert dass es eine genaue größe nicht überschreiten darf (anstattdessen soll es ein weiteres File generiert werden)

  1. Größe des Zip-Files?
    Wie groß kann ein Zipfile sein (maximum)?
  2. Aufteilung bei zu großem File?
    Wie kann man ansteuern dass man automatisch die Files die gezipped werden sollen, in blöcke aufgeteilt werden? zb. 1 Gb pro File (ohne dass ein File von denen die gezipped werden, aufgeteilt wird?

Vielen Dank Joekey

PS: ich benutze Unix-Shell für Mac OS X
 
Zuletzt bearbeitet:
Theoretisch können das bis zu 256TB werden, wenn das Programm damit umgehen kann. Um Dateien aufzuteilen kann split verwendet werden, das nimmt aber keine Rücksicht auf den Inhalt.
 
Hallo,

ob das mit Bordmitteln funktioniert, weiß ich nicht, aber hier ist ein Python-Script, was das erledigen können sollte. Habe es allerdings nicht bis ins Letzte durchgetestet.

PHP:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os.path
import time
import subprocess

class CompressAndSplit():

    def __init__(self):
        # Maximale Größe der zusammengestellten unkomprimierten Dateien
        self.maxsize = 1024 * 1024 * 100 # 100MB
        # Verzeichnis, in das die komprimierten Dateien hineinkopiert werden sollen
        self.outputfolder = "/Users/joekey/"

        # Initialisiere Listen. Nicht verändern!
        # Liste aller Dateien in Ordner
        self.mytuple = []
        # Temporäre Liste für Dateien in einem Zip-Archiv
        self.mytmptuple = []

    def add(self, file):
        # Füge alle Dateien in Ordner zu Liste mytuple hinzu
        if os.path.isfile(file):
            self.mytuple.append(os.path.abspath(file))
        elif os.path.isdir(file):
            for entry in os.listdir(file):
                self.add(file + "/" + entry)
        return

    def gettuplesize(self):
        # Berechne die Größe der Dateien in temporärer Liste
        calculate = 0
        for file in self.mytmptuple:
            calculate += os.path.getsize(file)
        return calculate

    def collect(self):
        # Arbeite Liste mytuple ab und entscheide was jeweils zu tun ist.
        if self.mytuple:
            currentfile = self.mytuple.pop()
            if self.maxsize > os.path.getsize(currentfile):
                if self.maxsize > self.gettuplesize() + os.path.getsize(currentfile):
                    # Dateien in temporärer Liste sind zusammen kleiner als maxsize
                    self.mytmptuple.append(currentfile)
                    # Rekursiver Aufruf, um temporäre Liste weiter zu befüllen
                    self.collect()
                else:
                    # Alte temporäre Dateien sichern
                    self.compress()
                    # Dateien in temporärer Liste sind zusammen kleiner als maxsize
                    self.mytmptuple.append(currentfile)
                    # Rekursiver Aufruf, um temporäre Liste weiter zu befüllen
                    self.collect()
            else:
                print "error: " + currentfile + " is bigger then maxsize. This file is excluded."
                self.collect()
        else:
            # Komprimiere die letzten Dateien in temporärer Liste, 
            # wenn Dateiliste bereits abgearbeitet ist
            if self.mytmptuple:
                self.compress()
        return

    def compress(self):
        # Komprimiere Dateien aus temporärer Liste
        if self.mytmptuple:
            cmd = ["zip", "-r", self.outputfolder + "/" + str(time.time()).replace(".", "") + ".zip"]
            cmd += self.mytmptuple
            process = subprocess.Popen(cmd)
            # Temporäre Liste leeren
            self.mytmptuple = []
        return

if __name__ == "__main__":
    if len(sys.argv) > 1:
        cas = CompressAndSplit()
        for file in sys.argv:
            if file != sys.argv[0]:
                # Sammle alle potentiellen Dateien
                cas.add(file)
        # Verarbeite alle gesammelten Dateien
        cas.collect()

Die Variablen
Code:
self.maxsize = 1024 * 1024 * 100
self.outputfolder = "/Users/joekey/"
müsstest du noch anpassen, je nachdem was du willst. self.maxsize entspricht der maximalen Größe der zusammengestellten Dateien.

Als Dateiname wird jeweils die aktuelle microtime angenommen und in self.outputfolder gespeichert.
Wäre schön, wenn du es mal testen würdest. So große Dateien habe ich hier nicht auf der Platte.

Aufgerufen wird das ganze mit python scriptname.py Verzeichnis1 [Verzeichnis2] [...]

Die Verzeichnisse werden rekursiv durchsucht. Symbolische Links werden nicht verfolgt.


cu
 
Zuletzt bearbeitet:
Hallo.

Danke für alle Hinweise. Was Python angeht, habe ich so weit noch keine Erfahrungen. Deswegen werde ich zuerst die Tar-Variante ausprobieren. Diesbezüglich hätte ich noch eine Frage:

Ist es möglich beim Tar-Befehl die Komprimierung zu überwachen? zB. so wie ich es vom zip kenne. Am ende bekommt man ein Bericht dass das File gezipped wurde und das Archiv auch die Kontrolle bestanden hat. (T- test the integrity of zip file)

Danke

LG joekey
 

Ähnliche Themen

Partitionen eines RAID1-Arrays verkleinern nach mdadm --grow

Welches Linux?

k3b erkennt wav dateien nicht

Firewall Log bei bestimmter Größe zippen und neu anfangen!

[SUSE 10.2] lvm-volume nicht mountbar

Zurück
Oben