C: théorie sur la façon d’extraire des fichiers d’un fichier archivé

Dans CI, vous avez créé un programme capable d’archiver plusieurs fichiers dans un fichier d’archive via la ligne de commande. par exemple

$echo 'file1/2' > file1/2.txt $./archive file1.txt file2.txt arhivedfile $cat archivedfile file1 file2 

Comment créer un processus pour que dans mon fichier archivé, j’ai:

 header file1 end header file2 end 

Ils sont tous stockés dans le fichier d’archive les uns après les autres. Je sais qu’il faut peut-être un fichier d’en-tête (contenant le nom de fichier, la taille du nom de fichier, le début et la fin du fichier) pour extraire ces fichiers dans leur format d’origine, mais comment procéder.

Je suis coincé sur où et comment commencer.

S’il vous plaît, pourriez-vous m’aider à comprendre la logique à suivre pour extraire des fichiers d’un fichier archivé?

Comme cela a été mentionné précédemment, commencez par l’algorithme. Vous avez déjà la plupart des détails.

Il y a quelques approches que vous pouvez prendre:

  1. Archive à access aléatoire.
  2. Archive à access séquentiel.

Archive à access aléatoire

Pour que cela fonctionne, l’en-tête doit agir en tant qu’index (comme les index de cartes dans une bibliothèque) en indiquant; a) où trouver le début de chaque fichier; et b) la longueur de chaque fichier. L’algorithme pour écrire le fichier archive pourrait ressembler à ceci:

  1. Obtenez une liste de tous les fichiers à partir de la ligne de commande.
  2. Créez une structure pour stocker les métadonnées sur chaque fichier: nom (255 caractères), taille (int de 64 bits), date et heure et permissions.
  3. Obtenez ses statistiques pour chaque fichier.
  4. Stocker les statistiques de chaque fichier dans un tableau de structures.
  5. Ouvrez l’archive pour l’écriture.
  6. Écrivez la structure d’en-tête.
  7. Pour chaque fichier, ajoutez son contenu au fichier archive.
  8. Fermez le fichier archive.

(L’en-tête devra peut-être aussi inclure le nombre de fichiers.)

Ensuite, l’algorithme d’extraction de fichiers:

  1. Obtenir un fichier d’archive à partir de la ligne de commande.
  2. Obtenez un nom de fichier à extraire, également à partir de la ligne de commande.
  3. Créez de la mémoire pour une structure permettant de lire des métadonnées sur chaque fichier.
  4. Lire toutes les métadonnées du fichier archive.
  5. Recherchez le nom du fichier à extraire dans la liste des métadonnées.
  6. Calculez le décalage dans le fichier archive pour le début du nom de fichier correspondant.
  7. Recherchez l’offset.
  8. Lisez le contenu du fichier et écrivez-le dans un nouveau fichier.
  9. Fermez le nouveau fichier.
  10. Fermez l’archive.

Accès séquentiel

C’est plus facile. Vous pouvez le faire vous-même: réfléchissez aux étapes.

A propos de la programmation

Il est facile de se perdre dans les détails de la façon dont quelque chose devrait fonctionner. Je vous suggère de prendre du recul – quelque chose que votre enseignant devrait discuter en classe – et d’essayer de réfléchir au problème à un niveau supérieur au codage, car:

  • l’algorithme que vous créez sera indépendant de la langue;
  • la correction des erreurs dans un algorithme, avant que le code soit écrit, est sortingviale;
  • vous aurez une meilleure compréhension de ce que vous devez faire avant de coder;
  • il faudra moins de temps pour mettre en œuvre la solution;
  • vous pouvez identifier des zones pouvant être mises en œuvre en parallèle;
  • vous verrez tous les obstacles potentiels à l’avance; et
  • vous serez sur le chemin des postes de direction en un rien de temps. 😉

Je pense que l’en-tête doit contenir les informations nécessaires pour identifier le fichier et indiquer sa taille dans l’archive – par exemple, le nom du fichier, le répertoire original et la taille, en lignes ou en octets, en fonction de l’utilité de votre fichier. le contexte. Vous aurez ensuite besoin de routines pour créer un en-tête, append un fichier à une archive (créer un en-tête et append les données du fichier), extraire un fichier d’une archive (suivre les en-têtes jusqu’à ce que l’entrée correcte soit trouvée et copier les données du fichier). archivez dans un fichier séparé) et supprimez un fichier (commencez à lire l’archive, copiez les données de toutes les entrées, à l’exception de celle que vous souhaitez supprimer, dans un nouveau fichier, supprimez l’ancienne archive et renommez la nouvelle en son ancien nom).

Partager et profiter.

Une approche consiste à imiter le format ZIP: http://en.wikipedia.org/wiki/ZIP_file_format

Il utilise une structure de répertoires à la fin du fichier, qui contient des pointeurs sur les décalages des fichiers de l’archive. Le gros avantage de cette structure est que vous pouvez trouver un fichier donné sans avoir à lire l’intégralité de l’archive, à condition de connaître le début du répertoire et d’avoir la possibilité d’accéder au fichier de manière aléatoire.

Une alternative est le format de fichier TAR: http://en.wikipedia.org/wiki/Tar_file_format

Ceci est conçu pour le streaming multimédia (“archive sur bande”), chaque entrée contient donc ses propres métadonnées. Vous devez parsingr l’intégralité du fichier pour rechercher une entrée, mais le cas d’utilisation normal consiste à compresser / décompacter des arborescences de répertoires entières, ce qui ne constitue pas une pénalité.

Le faire en continu, comme tar, est probablement la mise en œuvre la plus simple. Commencez par écrire un nombre magique afin de pouvoir identifier le format de votre archive. Je suggérerais ensuite d’utiliser stat (2) (c’est la syntaxe man pour la page de manuel stat, section 2) pour obtenir la taille du fichier à archiver. En fait, examinez de près les champs de statistiques à votre disposition. Vous voudrez peut-être conserver certaines informations intéressantes.

Ecrivez les informations dont vous avez besoin sous la forme tag = value, une par ligne. Par exemple:

 FileName=file1.txt FileSize=10 FileDir=./blah/blah FilePerms=0700 

Terminez votre en-tête avec deux nouvelles lignes afin que vous sachiez quand commencer à transférer des octets FileSize sur le disque. Vous n’avez pas besoin d’un marqueur de début d’en-tête, car vous connaissez la taille du fichier à écrire, vous savez donc quand commencer à parsingr votre en-tête.

Je suggère que vous utilisiez un format de texte pour vos informations d’en-tête, car vous n’avez pas à vous soucier de l’ordre des octets, etc., ce dont vous auriez à vous soucier si vous écrivez une structure binary brute sur le disque.

Lors de la lecture de votre archive, parsingz les lignes d’en-tête une par une et remplissez une structure locale contenant ces informations. Puis écrivez le fichier sur le disque et définissez les propriétés de fichier nécessitant une mise à jour en fonction des informations d’en-tête extraites.

J’espère que cela pourra aider. Bonne chance.