Il y a 5 fichiers énormes (fichier1, fichier2, .. fichier5) environ 10G chacun et très peu d'espace libre sur le disque et j'ai besoin de concaténer tous ces fichiers en un seul. Il n'est pas nécessaire de conserver les fichiers originaux, mais uniquement les fichiers finaux.
La concaténation habituelle va avec cat
en séquence pour les fichiers file2
.. file5
:
cat file2 >> file1 ; rm file2
Malheureusement, cette façon nécessite au moins 10G d'espace libre que je n'ai pas. Existe-t-il un moyen de concaténer des fichiers sans les copier, mais en indiquant au système de fichiers que le fichier1 ne se termine pas à la fin du fichier original1 et continue au début du fichier2?
ps. Le système de fichiers est ext4 si cela compte.
filesystems
files
se ruer
la source
la source
nbd-server
.Réponses:
Autant que je sache, il n’est (malheureusement) pas possible de tronquer un fichier depuis le début (cela peut être vrai pour les outils standard mais pour le niveau appel système, voir ici ). Mais en ajoutant une certaine complexité, vous pouvez utiliser la troncature normale (avec les fichiers fragmentés): vous pouvez écrire à la fin du fichier cible sans avoir écrit toutes les données entre les deux.
Supposons d’abord que les deux fichiers ont exactement 5 Gio (5120 Mio) et que vous souhaitez déplacer 100 Mio à la fois. Vous exécutez une boucle qui consiste en
tronquer le fichier source d'un bloc (libérer de l'espace disque)
Mais essayez d'abord avec des fichiers de test plus petits, s'il vous plaît ...
Les fichiers ne sont probablement ni de la même taille ni des multiples de la taille du bloc. Dans ce cas, le calcul des compensations devient plus compliqué.
seek_bytes
etskip_bytes
devrait être utilisé alors.Si c'est ce que vous voulez faire mais que vous avez besoin d'aide pour les détails, demandez à nouveau.
Attention
En fonction de la
dd
taille du bloc, le fichier résultant sera un cauchemar de fragmentation.la source
Au lieu de regrouper les fichiers en un seul fichier, simulez peut-être un seul fichier avec un canal nommé, si votre programme ne peut pas gérer plusieurs fichiers.
Comme le suggère Hauke, losetup / dmsetup peut également fonctionner. Une expérience rapide; J'ai créé 'file1..file4' et avec un peu d'effort, j'ai:
Ensuite, / dev / dm-0 contient un périphérique de bloc virtuel avec votre fichier en tant que contenu.
Je n'ai pas bien testé.
Autre édition: la taille du fichier doit être divisible par 512. Dans le cas contraire, vous perdrez certaines données. Si c'est le cas, ça va. Je vois qu'il a également noté cela ci-dessous.
la source
dmsetup
un périphérique de bloc virtuel (ce qui permet des opérations de recherche normales mais ni les ajouts ni les tronques). Si la taille du premier fichier n'est pas un multiple de 512, vous devez copier le dernier secteur incomplet et les premiers octets du deuxième fichier (somme 512) dans un troisième fichier. Le périphérique de boucle pour le second fichier aurait--offset
alors besoin .Vous devrez écrire quelque chose qui copie les données dans des groupes dont la taille est au plus égale à la quantité d'espace libre dont vous disposez. Cela devrait fonctionner comme ceci:
file2
(utiliserpread()
en cherchant avant la lecture au bon endroit).file1
.fcntl(F_FREESP)
pour désallouer l'espace defile2
.la source
fcntl(F_FREESP)
cela libère l'espace associé à une plage d'octets donnée du fichier (cela le rend clairsemé).fcntl
page de manuel (2012-04-15).fallocate
appel système. Les versions les plus récentes de l'utilitaire fallocateutil-linux
ont une interface pour cela.Je sais que c'est plus une solution de contournement que ce que vous avez demandé, mais cela réglerait votre problème (et avec un minimum de fragmentation ou de blessure à la tête):
et alors
ou, si vous pensez que la compression aiderait:
Alors (et UNIQUEMENT alors), enfin
la source