Question

Supposons que vous souhaitiez concaténer deux fichiers volumineux (plusieurs Go), mais que vous disposiez de très peu d’espace disque disponible (quelques centaines de Mo). Autrement dit, étant donné fichier1 et fichier2 , vous souhaitez vous retrouver avec un seul fichier résultant de la concaténation de fichier1 et de fichier2. ainsi que, octet par octet, supprimez les fichiers d'origine.

Vous ne pouvez pas créer l'évident cat file2 > > fichier1; rm file2 , car entre les deux opérations, vous manqueriez d'espace disque.

Les solutions sur toutes les plateformes avec des outils gratuits ou non gratuits sont les bienvenues. C’est un problème hypothétique que j’ai imaginé alors que je téléchargeais un fichier ISO Linux l’autre jour, et le téléchargement s’est interrompu à mi-parcours à cause d’un problème sans fil.

Était-ce utile?

La solution

Je pense que la difficulté consiste à déterminer comment récupérer l'espace disponible à partir des fichiers d'origine.

Je pense que les solutions suivantes pourraient fonctionner:

  1. Allouer un fichier fragmenté du taille combinée.
  2. Copiez 100 Mo de la fin du deuxième fichier à la fin du nouveau fichier.
  3. Tronquez 100 Mo de la fin du deuxième fichier
  4. Boucle 2 & 3 jusqu'à la fin du deuxième fichier (avec 2. modifié à la place du fichier de destination).
  5. Faites 2 & 3 & 4 mais avec le premier fichier.

Tout cela repose sur la prise en charge des fichiers fragmentés et sur la troncature des fichiers, libérant immédiatement de l'espace.

Si vous vouliez réellement faire cela, vous devriez étudier la commande dd . qui peut faire l'étape de copie

Quelqu'un dans une autre réponse a donné une solution soignée qui ne nécessite pas de fichiers fragmentés, mais copie le fichier 2 deux fois:

  1. Copiez des fragments de 100 Mo de la fin du fichier 2 dans un nouveau fichier 3, en procédant dans l’ordre inverse. Tronquer le fichier 2 au fur et à mesure.
  2. Copiez des morceaux de 100 Mo de la fin du fichier 3 dans le fichier 1 pour les placer dans leur ordre d'origine, à la fin du fichier 1. Tronquer le fichier 3 au fur et à mesure.

Autres conseils

Temps passé à trouver une solution intelligente impliquant un brassage dans le secteur du disque et une manipulation de la chaîne de fichiers: 2 à 4 heures

temps requis pour acquérir / écrire un logiciel permettant de copier et tronquer sur place: 2 à 20 heures

fois le tarif médian du programmeur à 50 $ l'heure: 400 $ à 1 200 $

coût de la clé USB de 1 To: 100 $ - 200 $

capacité à comprendre l'expression "coût d'opportunité": inestimable

Voici une légère amélioration par rapport à mes première réponse .

Si vous disposez de 100 Mo d'espace libre, copiez les 100 derniers Mo du deuxième fichier et créez un troisième fichier. Tronquez le deuxième fichier pour qu'il soit maintenant 100 Mo plus petit. Répétez cette procédure jusqu'à ce que le second fichier soit complètement décomposé en morceaux individuels de 100 Mo.

Chacun de ces fichiers de 100 Mo peut maintenant être ajouté au premier fichier, un à la fois.

Avec ces contraintes, je pense que vous devrez modifier le système de fichiers. éditez directement la taille du fichier et les blocs d’attribution.

En d'autres termes, oubliez de mélanger tous les blocs de contenu de fichier, éditez simplement les informations relatives à ces fichiers.

si le fichier est très compressible (c'est-à-dire les journaux):

gzip file1

gzip file2

zcat file1 file2 | gzip > file3

rm file1

rm file2

gunzip file3

Au risque de paraître désinvolte, avez-vous envisagé la possibilité d’obtenir un disque plus volumineux? Ce serait probablement plus rapide ...

Pas très efficace, mais je pense que cela peut être fait.

Ouvrez le premier fichier en mode ajout et copiez-y les blocs du deuxième fichier jusqu'à ce que le disque soit presque plein. Pour le reste du deuxième fichier, copiez des blocs à partir du point où vous vous êtes arrêté au début du fichier via des E / S à accès aléatoire. Tronquez le fichier après avoir copié le dernier bloc. Répéter jusqu'à la fin.

Évidemment, la réponse économique est d’acheter plus de stockage en supposant que c’est une réponse possible. Cependant, il se peut que ce ne soit pas un système intégré, sans aucun moyen d’attacher plus de mémoire, ni même d’accéder au matériel lui-même, par exemple une sonde spatiale en vol.

La réponse présentée précédemment, basée sur le système de fichiers fragmenté, est bonne (à l'exception de sa nature destructive si quelque chose ne va pas!) si vous avez un système de fichiers fragmenté. Et si tu ne le fais pas, cependant?

À partir de la fin du fichier, copiez les blocs au début du fichier cible en les inversant au fur et à mesure. Après chaque bloc, vous tronquez le fichier source à la longueur non copiée. Répétez l'opération pour le fichier n ° 1.

À ce stade, le fichier cible contient toutes les données en arrière, les fichiers source ont disparu.

Lisez un bloc de la tarte et de la fin du fichier cible, inversez-les et écrivez-les à l’endroit où l’autre est venu. Frayez-vous un chemin en retournant des blocs.

Lorsque vous avez terminé, le fichier cible est la concaténation des fichiers source. Aucun système de fichiers fragmenté n'est nécessaire, aucun problème avec le système de fichiers requis. Ceci peut être effectué à zéro octet libre car les données peuvent être conservées en mémoire.

ok, pour un divertissement théorique, et seulement si vous vous engagez à ne pas perdre votre temps à le faire:

    Les fichiers
  • sont stockés sur le disque en morceaux
  • les morceaux sont liés dans une chaîne

Vous pouvez donc concaténer les fichiers par:

  • lier le dernier morceau du premier fichier au premier morceau du dernier fichier
  • modifier l'entrée du répertoire du premier fichier pour changer le dernier morceau et la taille du fichier
  • supprimer l'entrée de répertoire du dernier fichier
  • nettoyage du marqueur de fin de fichier du premier fichier, le cas échéant
  • Notez que si le dernier segment du premier fichier n’est que partiellement rempli, vous devrez copier les données "up". les segments du dernier fichier pour éviter d'avoir des ordures au milieu du fichier [merci @Wedge!]

Cela serait extrêmement efficace: modifications minimes, copie minimale, aucun espace disque disponible requis.

maintenant, achetez une clé USB ;-)

Deux pensées:

Si vous avez assez de RAM physique, vous pouvez réellement lire le deuxième fichier entièrement en mémoire, le supprimer, puis l'écrire en mode ajout dans le premier fichier. Bien sûr, si vous perdez le pouvoir après la suppression, mais avant la fin de l'écriture, vous perdez définitivement une partie du second fichier.

Réduisez temporairement l'espace disque utilisé par la fonctionnalité du système d'exploitation (par exemple, mémoire virtuelle, "corbeille" ou similaire). Probablement seulement utile sous Windows.

Je doute que ce soit une réponse directe à la question. Vous pouvez considérer cela comme un moyen alternatif de résoudre le problème.

Je pense qu'il est possible de considérer le deuxième fichier comme la partie 2 du premier fichier. Habituellement, dans l’application zip, nous verrions un gros fichier divisé en plusieurs parties. Si vous ouvrez la première partie, l'application considère automatiquement les autres parties lors du traitement ultérieur.

Nous pouvons simuler la même chose ici. Comme @edg l'a fait remarquer, bricoler le système de fichiers serait un moyen.

vous pouvez faire ceci:

head file2 --bytes=1024 >> file1 && tail --bytes=+1024 file2 >file2 

vous pouvez augmenter de 1024 points en fonction de votre espace disque supplémentaire, puis répétez l'opération jusqu'à ce que tous les octets aient été déplacés.

C’est probablement le moyen le plus rapide de le faire (en termes de temps de développement)

Vous pourrez peut-être gagner de la place en compressant l’ensemble du système de fichiers. Je pense que NTFS prend cela en charge, et je suis sûr que divers systèmes de fichiers * nix le prendraient en charge. Si vous copiez les fichiers, vous aurez également l’avantage de disposer de plus d’espace disque que lorsque vous avez démarré.

OK, modifiez un peu le problème. Il y a des chances qu'il y ait sur le disque d'autres éléments dont vous n'avez pas besoin, mais vous ne savez pas ce que c'est ni où. Si vous pouviez le trouver, vous pourriez le supprimer et vous auriez peut-être assez d'espace supplémentaire.

Pour trouver ces "tumeurs", qu’il s’agisse de quelques grosses ou de beaucoup de petites, j’utilise un petit programme d’échantillonnage. En partant du haut d'un répertoire (ou de la racine), il effectue deux passes. À l'étape 1, il parcourt l'arborescence des répertoires, en additionnant la taille de tous les fichiers pour obtenir un total de N octets. Dans le passage 2, il parcourt à nouveau l’arborescence de répertoires, prétendant lire tous les fichiers. Chaque fois qu'il passe à N / 20 octets, il affiche le chemin du répertoire et le nom du fichier qu'il est en train de "lire". Le résultat final est donc 20 échantillons approfondis de noms de chemins répartis uniformément sur tous les octets du répertoire.

Ensuite, il suffit de regarder cette liste pour trouver des éléments qui ne sont pas nécessaires, puis de les supprimer.

(C'est l'équivalent en espace de la méthode d'échantillonnage que j'utilise pour optimiser les performances.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top