Recherche de site Web

Comment créer et manipuler des archives tar à l’aide de Python


Sur Linux et d’autres systèmes d’exploitation de type Unix, tar est sans aucun doute l’un des utilitaires d’archivage les plus utilisés ; Il nous a permis de créer des archives, souvent appelées « tarballs », que nous pouvons utiliser à des fins de distribution ou de sauvegarde du code source. Dans ce tutoriel, nous allons voir comment lire, créer et modifier des archives tar avec python, en utilisant le module tarfile.

Dans ce tutoriel, vous allez apprendre :

  • Les modes d’ouverture d’une archive tar à l’aide du module tarfile
  • Que sont les classes TarInfo et TarFile et ce qu’elles représentent
  • Comment lister le contenu d’une archive tar
  • Comment extraire le contenu d’une archive tar
  • Comment ajouter des fichiers à une archive tar
  • Le nom de l’archive tar à laquelle nous voulons accéder
  • Le mode d’ouverture

Le « mode » utilisé pour ouvrir une archive tar dépend de l’action que nous voulons effectuer et du type de compression (le cas échéant) utilisé. Voyons-les ensemble.

Ouverture d’une archive en lecture seule

Si nous voulons examiner ou extraire le contenu d’une archive tar, nous pouvons utiliser l’un des modes suivants, pour l’ouvrir en lecture seule :

ModeSignification
'R'Mode lecture seule – le type de compression sera automatiquement géré
'r :'Mode lecture seule sans compression
'r :gz'Mode lecture seule – compression zip explicitement spécifiée
'r :bz2'Mode lecture seule – compression bzip explicitement spécifiée
'r :xz'Mode lecture seule – compression lzma explicitement spécifiée

Dans la plupart des cas, où la méthode de compression peut être facilement détectée, le mode recommandé à utiliser est 'r'.

Ouverture d’une archive pour ajouter des fichiers

Si nous voulons ajouter des fichiers à une archive existante, nous pouvons utiliser le mode 'a'. Il est important de noter qu’il n’est possible d’ajouter à une archive que si elle n’est pas compressée ; si nous tentons d’ouvrir une archive compressée avec ce mode, une exception ValueError sera levée. Si nous faisons référence à une archive inexistante, elle sera créée à la volée.

Ouvrir une archive pour l’écriture

Si nous voulons créer explicitement une nouvelle archive et l’ouvrir à l’écriture, nous pouvons utiliser l’un des modes suivants :

ModeSignification
'W'Ouvrez l’archive pour l’écriture – n’utilisez pas de compression
'w :gz'Ouvrez l’archive pour l’écriture – utilisez la compression gzip
'w :bz'Ouvrez l’archive pour l’écriture – utilisez la compression bzip2
'w :xz'Ouvrez l’archive pour l’écriture – utilisez la compression lzma

Si un fichier d’archive existant est ouvert pour l’écriture, il est tronqué, de sorte que tout son contenu est ignoré. Pour éviter de telles situations, nous pouvons ouvrir l’archive exclusivement, comme décrit dans la section suivante.

Créer une archive uniquement si elle n’existe pas

Lorsque nous voulons être sûrs qu’un fichier existant n’est pas remplacé lors de la création d’une archive, nous devons l’ouvrir exclusivement. Si nous utilisons le mode 'x' et qu’un fichier portant le même nom que celui que nous avons spécifié pour l’archive existe déjà, une FileExistsError sera levée. Les méthodes de compression peuvent être spécifiées comme suit :

ModeSignification
'x'Créez l’archive sans compression si elle n’existe pas
'x :gz'Créez l’archive avec la compression gzip uniquement si elle n’existe pas
'x :bz2'Ne créez l’archive avec la compression bzip2 que si elle n’existe pas
'x :xz'Ne créez l’archive avec la compression lzma que si elle n’existe pas

Travailler avec les archives

Il y a deux classes fournies par le module tarfile qui sont utilisées pour interagir avec les archives tar et leur contenu, et sont, respectivement : TarFile et TarInfo. Le premier est utilisé pour représenter une archive tar dans son intégralité et peut être utilisé comme gestionnaire de contexte avec l’instruction Python with, le second est utilisé pour représenter un membre de l’archive et contient diverses informations à son sujet. Dans un premier temps, nous nous concentrerons sur certaines des méthodes les plus souvent utilisées de la classe TarFile : nous pouvons les utiliser pour effectuer des opérations courantes sur les archives tar.

Récupération d’une liste des membres de l’archive

Pour récupérer une liste des membres de l’archive, nous pouvons utiliser la méthode getmembers d’un objet TarFile. Cette méthode renvoie une liste d’objets TarInfo, un pour chaque membre de l’archive. Voici un exemple de son utilisation avec une archive compressée factice contenant deux fichiers :

>>> with tarfile.open('archive.tar.gz', 'r') as archive:
...     archive.getmembers()
...
[<TarInfo 'file1.txt' at 0x7f58dab50d00>, <TarInfo 'file2.txt' at 0x7f58dab50ac0>]

Comme nous le verrons plus tard, nous pouvons accéder à certains des attributs d’un fichier archivé, comme sa propriété et son temps de modification, via les propriétés et méthodes de l’objet TarInfo correspondantes.

Affichage du contenu d’une archive tar

Si tout ce que nous voulons faire est d’afficher le contenu d’une archive tar, nous pouvons l’ouvrir en mode lecture et utiliser la méthode list de la classe Tarfile.

>>> with tarfile.open('archive.tar.gz', 'r') as archive:
...     archive.list()
...
?rw-r--r-- egdoc/egdoc          0 2020-05-16 15:45:45 file1.txt
?rw-r--r-- egdoc/egdoc          0 2020-05-16 15:45:45 file2.txt

Comme vous pouvez le voir, la liste des fichiers contenus dans l’archive est affichée en sortie. La méthode list accepte un paramètre positionnel, verbose, qui est True par défaut. Si nous changeons sa valeur sur False, seuls les noms de fichiers seront signalés dans la sortie, sans informations supplémentaires.

La méthode accepte également un paramètre nommé facultatif, members. S’il est utilisé, l’argument fourni doit être un sous-ensemble de la liste d’objets TarInfo renvoyée par la méthode getmembers. Seules les informations relatives aux fichiers spécifiés seront affichées si ce paramètre est utilisé et qu’une valeur correcte est fournie.

Extraction de tous les membres de l’archive tar

Une autre opération très courante que nous pouvons vouloir effectuer sur une archive tar est d’extraire tout son contenu. Pour effectuer une telle opération, nous pouvons utiliser la méthode extractallde l’objet TarFile correspondant. Voici ce que nous écririons :

>>> with tarfile.open('archive.tar.gz', 'r') as archive:
...     archive.extractall()

Le premier paramètre accepté par la méthode est path : il permet de spécifier où les membres de l’archive doivent être extraits. La valeur par défaut est '.', de sorte que les membres sont extraits dans le répertoire de travail actuel.

Le deuxième paramètre, members, peut être utilisé pour spécifier un sous-ensemble de membres à extraire de l’archive et, comme dans le cas de la méthode list, il doit s’agir d’un sous-ensemble de la liste renvoyé par la méthode getmembers.

La méthode extractall a également un paramètre nommé, numeric_owner. Il est False par défaut : si nous le changeons en True, les chiffres uid et gid seront utilisés pour définir la propriété des fichiers extraits à la place des noms d’utilisateur et de groupe.

Extraction d’un seul membre de l’archive

Que se passe-t-il si nous voulons extraire un seul fichier de l’archive ? Dans ce cas, nous voulons utiliser la méthode extract et référencer le fichier qui doit être extrait par son nom (ou en tant qu’objet TarFile). Par exemple, pour extraire uniquement le fichier file1.txt de l’archive tar, nous exécuterions :

>>> with tarfile.open('archive.tar.gz', 'r') as archive:
...     archive.extract('file1.txt')

Facile, n’est-ce pas ? Le fichier est extrait par défaut dans le répertoire de travail courant, mais une position différente peut être spécifiée à l’aide du deuxième paramètre accepté par la méthode : path.

Normalement, les attributs que le fichier a à l’intérieur de l’archive sont définis lorsqu’il est extrait sur le système de fichiers ; pour éviter ce comportement, nous pouvons définir le troisième paramètre de la fonction, set_attrs, à False.

La méthode accepte également le paramètre numeric_owner : l’utilisation est la même, nous l’avons vu dans le cadre de la méthode extractall.

Extraction d’un membre d’archive en tant qu’objet de type fichier

Nous avons vu comment, en utilisant les méthodes extractall et extract, nous pouvons extraire un ou plusieurs membres de l’archive tar dans le système de fichiers. Le module tarfile propose une autre méthode d’extraction : extractfile. Lorsque cette méthode est utilisée, le fichier spécifié n’est pas extrait dans le système de fichiers ; Au lieu de cela, un objet de type fichier en lecture seule le représentant est renvoyé :

>>> with tarfile.open('archive.tar.gz', 'r') as archive:
...     fileobj = archive.extractfile('file1.txt')
...     fileobj.writable()
...     fileobj.read()
...
False
b'hello\nworld\n'

Ajout de fichiers à une archive

Jusqu’à présent, nous avons vu comment obtenir des informations sur une archive et ses membres, et les différentes méthodes que nous pouvons utiliser pour extraire son contenu ; Il est maintenant temps de voir comment nous pouvons ajouter de nouveaux membres.

La méthode la plus simple pour ajouter un fichier à une archive est d’utiliser la méthode add. Nous référenceons le fichier à inclure dans l’archive par son nom, qui est le premier paramètre accepté par la méthode. Le fichier sera archivé avec son nom d’origine, à moins que nous n’en spécifiions un autre en utilisant le deuxième paramètre de position : arcname. Supposons que nous voulions ajouter le file1.txt à une nouvelle archive, mais que nous voulions le stocker en tant que archived_file1.txt ; Nous écririons :

>>> with tarfile.open('new_archive.tar.gz', 'w') as archive:
...     archive.add('file1.txt', 'archived_file1.txt')
...     archive.list()
...
-rw-r--r-- egdoc/egdoc         12 2020-05-16 17:49:44 archived_file1.txt

Dans l’exemple ci-dessus, nous avons créé une nouvelle archive non compressée en utilisant le mode 'w' et ajouté le file1.txt comme archive_file1.txt, comme vous pouvez le voir par la sortie de list().

Les répertoires peuvent être archivés de la même manière : par défaut, ils sont ajoutés de manière récursive, donc avec leur contenu. Ce comportement peut être modifié en définissant le troisième paramètre positionnel accepté par la méthode add, récursive, sur False.

Que se passe-t-il si nous voulons appliquer un filtre, de sorte que seuls les fichiers spécifiés soient inclus dans l’archive ? À cette fin, nous pouvons utiliser le filtre facultatif nommé parameter. La valeur passée à ce paramètre doit être une fonction qui prend un objet TarInfo comme argument et renvoie ledit objet s’il doit être inclus dans l’archive ou None s’il doit être exclu. Voyons un exemple. Supposons que nous ayons trois fichiers dans notre répertoire de travail actuel : file1.txt, file2.txt et file1.md. Nous voulons ajouter uniquement les fichiers avec l’extension .txt à l’archive ; Voici ce que l’on pourrait écrire :

>>> import os
>>> import tarfile
>>> with tarfile.open('new_archive.tar.gz', 'w') as archive:
...     for i in os.listdir():
...         archive.add(i, filter=lambda x: x if x.name.endswith('.txt') else None)
...     archive.list()
...
-rw-r--r-- egdoc/egdoc          0 2020-05-16 18:26:20 file2.txt
-rw-r--r-- egdoc/egdoc          0 2020-05-16 18:22:13 file1.txt

Dans l’exemple ci-dessus, nous avons utilisé la méthode os.listdir pour obtenir une liste des fichiers contenus dans le répertoire de travail actuel. En itérant sur ladite liste, nous avons utilisé la méthode add pour ajouter chaque fichier à l’archive. Nous avons passé une fonction en argument du paramètre filter, dans ce cas une fonction anonyme, une lambda. La fonction prend l’objet tarfile comme argument (x) et le renvoie si son nom (le nom est l’une des propriétés de l’objet TarInfo) se termine par « .txt « . Si ce n’est pas le cas, la fonction renvoie None donc le fichier n’est pas archivé.

L’objet TarInfo

Nous avons déjà appris que les objets TarInfo représentent un membre de l’archive tar : ils stockent les attributs du fichier référencé et fournissent certaines méthodes qui peuvent nous aider à identifier le type de fichier lui-même. L’objet TarInfo ne contient pas les données de fichier réelles. Voici quelques-uns des attributs de l’objet TarInfo :

  • name (nom du fichier)
  • size (taille du fichier)
  • mtime (temps de modification du fichier)
  • uid (l’ID utilisateur du propriétaire du fichier)
  • gid (l’ID du groupe de fichiers)
  • uname (nom d’utilisateur du propriétaire du fichier)
  • gname (nom du groupe de fichiers)

L’objet dispose également de méthodes très utiles, en voici quelques-unes :

  • isfile() – Renvoie True si le fichier est un fichier normal, False dans le cas contraire.
  • isdir() – Renvoie True si le fichier est un répertoire, False dans le cas contraire
  • issym() – Renvoie True si le fichier est un lien symbolique, False dans le cas contraire
  • isblk() – Renvoie True si le fichier est un périphérique bloc, False dans le cas contraire

Conclusions

Dans ce tutoriel, nous avons appris l’utilisation de base du module python tarfile, et nous avons vu comment nous pouvons l’utiliser pour travailler avec des archives tar. Nous avons vu les différents modes de fonctionnement, ce que représentent les classes TarFile et TarInfo, et certaines des méthodes les plus utilisées pour lister le contenu d’une archive, ajouter de nouveaux fichiers ou les extraire. Pour une connaissance plus approfondie du module tarfile, veuillez consulter la documentation officielle du module

Articles connexes: