Créez rapidement un gros fichier sur un système Linux

439

Comment créer rapidement un fichier volumineux sur un système Linux ( Red Hat Linux )?

dd fera le travail, mais la lecture /dev/zeroet l'écriture sur le lecteur peuvent prendre beaucoup de temps lorsque vous avez besoin d'un fichier de plusieurs centaines de Go pour tester ... Si vous devez le faire à plusieurs reprises, le temps s'additionne vraiment.

Je me fiche du contenu du fichier, je veux juste qu'il soit créé rapidement. Comment cela peut-il être fait?

L'utilisation d'un fichier clairsemé ne fonctionnera pas pour cela. J'ai besoin d'allouer de l'espace disque au fichier.

DrStalker
la source
1
Ext4 a de bien meilleures performances d'allocation de fichiers, car des blocs entiers allant jusqu'à 100 Mo peuvent être alloués à la fois.
martinus
5
La commande 'tronquer' crée un fichier clairsemé, soit dit en passant. Voir par exemple en.wikipedia.org/wiki/Sparse_file
Jason Drew
2
Les gens semblent ignorer grossièrement le "fichier clairsemé ne fonctionnera pas avec cela", avec leur recherche tronquée et dd ci-dessous.
hpavc
1
Vous auriez dû définir ce que vous vouliez dire par "pour tester". Vous testez la vitesse d'écriture de votre disque dur? Tester ce qui dfva rapporter? Tester une application qui fait quelque chose de particulier. La réponse dépend de ce que vous voulez tester. Quoi qu'il en soit, je suis un peu en retard - je vois maintenant que cela fait des années que votre question :-)
ndemou
1
Juste au cas où vous cherchez un moyen de simuler une partition complète, comme moi, ne cherchez pas plus loin que / dev / full
Julian

Réponses:

510

dddes autres réponses est une bonne solution, mais elle est lente à cet effet. Sous Linux (et d'autres systèmes POSIX), nous avons fallocate, qui utilise l'espace souhaité sans avoir à y écrire, fonctionne avec la plupart des systèmes de fichiers sur disque modernes, très rapidement:

Par exemple:

fallocate -l 10G gentoo_root.img
Franta
la source
5
Est-il possible que dd l'utilise déjà en interne? Si je fais 'dd if = / dev / zero of = zerofile bs = 1G count = 1' sur un noyau 3.0.0, l'écriture se termine en 2 secondes, avec un débit de données d'écriture de plus de 500 mégaoctets par seconde. C'est clairement impossible sur un disque dur de 2,5
pouces pour
21
fallocateest exactement ce que je cherchais.
AB
7
Cela ( fallocate) ne fonctionnera pas non plus sur un système de fichiers Linux ZFS - github.com/zfsonlinux/zfs/issues/326
Joe
5
fallocate n'est pas non plus supporté par ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie
3
Dans Debian, GNU / Linux fallocatefait partie du util-linuxpaquet. Cet outil a été écrit par Karel Zak de RedHat et le code source peut être trouvé ici: kernel.org/pub/linux/utils/util-linux
Franta
295

C'est une question courante - en particulier dans l'environnement actuel d'environnements virtuels. Malheureusement, la réponse n'est pas aussi simple qu'on pourrait le penser.

dd est le premier choix évident, mais dd est essentiellement une copie et cela vous oblige à écrire chaque bloc de données (donc, à initialiser le contenu du fichier) ... Et cette initialisation est ce qui prend tellement de temps d'E / S. (Vous voulez que cela prenne encore plus de temps? Utilisez / dev / random au lieu de / dev / zero ! Ensuite, vous utiliserez le CPU ainsi que le temps d'E / S!) En fin de compte, dd est un mauvais choix (bien que essentiellement le utilisé par défaut par les interfaces graphiques "créer" de la machine virtuelle). Par exemple:

dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G

tronquer est un autre choix - et est probablement le plus rapide ... Mais c'est parce qu'il crée un "fichier clairsemé". Essentiellement, un fichier clairsemé est une section de disque qui contient beaucoup des mêmes données, et le système de fichiers sous-jacent "triche" en ne stockant pas vraiment toutes les données, mais simplement en "prétendant" qu'elles sont toutes là. Ainsi, lorsque vous utilisez tronquer pour créer un lecteur de 20 Go pour votre machine virtuelle, le système de fichiers n'alloue pas réellement 20 Go, mais il triche et dit qu'il y a 20 Go de zéros, même si une seule piste sur le disque peut en fait (vraiment) être utilisé. Par exemple:

 truncate -s 10G gentoo_root.img

fallocate est le dernier - et le meilleur - choix à utiliser avec l'allocation de disque VM, car il "réserve" (ou "alloue" tout l'espace que vous recherchez, mais il ne prend pas la peine d'écrire quoi que ce soit. Donc, lorsque vous utilisez fallocate pour créer un espace de lecteur virtuel de 20 Go, vous obtenez vraiment un fichier de 20 Go (pas un "fichier épars", et vous n'aurez pas pris la peine d'y écrire quoi que ce soit - ce qui signifie pratiquement tout pourrait être dans là - un peu comme un tout nouveau disque!) Par exemple:

fallocate -l 10G gentoo_root.img
Dan McAllister
la source
4
+1 truncateest fonctionnel sur JFS; fallocate, pas tellement. Un point: vous ne pouvez pas inclure une décimale dans le nombre, je devais le préciser 1536G, non 1.5T.
Calrion
1
Selon ma fallocatepage de manuel, cela est uniquement pris en charge btrfs, ext4, ocfs2et les xfssystèmes de fichiers
Nathan S. Watson-Haigh
Remarque swaponne fonctionne malheureusement pas sur les extensions pré-allouées, la dernière fois que j'ai vérifié. Il y a eu une discussion sur la liste de diffusion XFS sur la possibilité d'avoir une option fallocate pour exposer les anciennes données d'espace libre à la place et ne pas avoir l'étendue marquée comme préallouée, donc swapon fonctionnerait. Mais je ne pense pas que quelque chose ait été fait.
Peter Cordes
1
Pour info, essayer de lire trop de données /dev/randompeut entraîner un épuisement des données aléatoires, et "Lorsque le pool d'entropie est vide, les lectures de / dev / random se bloqueront jusqu'à ce que du bruit environnemental supplémentaire soit collecté" donc cela pourrait prendre très très très long time
Xen2050
154

Linux et tous les systèmes de fichiers

xfs_mkfile 10240m 10Gigfile

Linux et certains systèmes de fichiers (ext4, xfs, btrfs et ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS et probablement d'autres UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Explication

Essayez mkfile <size>myfile comme alternative à dd. Avec l' -noption, la taille est notée, mais les blocs de disque ne sont pas alloués tant que les données n'y sont pas écrites. Sans l' -noption, l'espace est rempli de zéro, ce qui signifie écrire sur le disque, ce qui signifie prendre du temps.

mkfile est dérivé de SunOS et n'est pas disponible partout. La plupart des systèmes Linux ont xfs_mkfilequi fonctionne exactement de la même manière, et pas seulement sur les systèmes de fichiers XFS malgré le nom. Il est inclus dans xfsprogs (pour Debian / Ubuntu) ou dans des packages nommés similaires.

La plupart des systèmes Linux ont également fallocate, qui ne fonctionne que sur certains systèmes de fichiers (tels que btrfs, ext4, ocfs2 et xfs), mais est le plus rapide, car il alloue tout l'espace fichier (crée des fichiers non troués) mais n'en initialise aucun de celui-ci.

CMS
la source
5
Où est ce mkfile dont vous parlez, étranger? Ce n'est pas dans l'installation RHEL par défaut.
paxdiablo
2
C'est un utilitaire Solaris. si vous recherchez gpl mkfile, vous trouverez des exemples de code source.
Martin Beckett
5
Fonctionne comme un charme sur OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose
2
xfs_mkfileest inclus dans xfsprogs sur Ubuntu et fonctionne comme un charme sur mon ext3 fs. :)
Greg Dubicki
97
truncate -s 10M output.file

va créer un fichier de 10 M instantanément (M signifie 1024 * 1024 octets, MB signifie 1000 * 1000 - même avec K, KB, G, GB ...)

EDIT: comme beaucoup l'ont souligné, cela n'allouera pas physiquement le fichier sur votre appareil. Avec cela, vous pouvez réellement créer un fichier volumineux arbitraire, quel que soit l'espace disponible sur l'appareil, car il crée un fichier "clairsemé".

Ainsi, en faisant cela, vous reporterez l'allocation physique jusqu'à ce que le fichier soit accédé. Si vous mappez ce fichier à la mémoire, vous pouvez ne pas avoir les performances attendues.

Mais c'est toujours une commande utile à connaître

kiv
la source
1
J'ai essayé, mais cela n'affecte pas l'espace disque disponible. Doit parce que c'est un fichier clairsemé comme décrit précédemment.
Gringo Suave
7
Cela ne devrait pas être la meilleure réponse car cela ne résout pas le problème, la fallocateréponse ci-dessous le fait.
Gringo Suave
4
@GringoSuave mais cela est toujours utile pour certaines personnes qui peuvent avoir un problème similaire mais légèrement différent.
AJMansfield
@GringoSuave: Il semble créer un gros fichier comme demandé, pourquoi ne résout-il pas le problème? Il y a aussi des notes sous la réponse fallacate qui ne fonctionnent même pas dans la plupart des cas.
Pavel Šimerda
1
Pourquoi suggérer de créer des fichiers clairsemés quand il a dit que cela ne fonctionnerait pas?
hpavc
44

Où rechercher est la taille du fichier souhaité en octets - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Zoredache
la source
6
J'aime cette approche, mais le commentateur ne veut pas de fichier clairsemé pour une raison quelconque. :(
éphémère
3
dd if = / dev / zero of = 1GBfile bs = 1000 count = 1000000
Damien
7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret
1
Pour les fichiers clairsemés, truncatesemble être beaucoup mieux.
Pavel Šimerda
36

Exemples où recherche est la taille du fichier que vous souhaitez en octets

#kilobytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200K

#megabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200M

#gigabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200G

#terabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200T


Depuis la page de manuel dd:

BLOCS et BYTES peuvent être suivis des suffixes multiplicatifs suivants: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024, et ainsi de suite pour T, P, E, Z, Y.

Sepero
la source
Cela semble beaucoup mieux que la méthode n-1 , il est donc fondamentalement équivalent à truncate.
Pavel Šimerda
19

Pour créer un fichier de 1 Go:

dd if=/dev/zero of=filename bs=1G count=1
max
la source
7
Je crois que le nombre doit être 1. (testé sur centos)
SvennD
dd if=/dev/zero of=filename bs=20G count=1ne créera qu'un fichier de 2 Go! pas 20 Go.
Maulik Gangani
18

Je ne connais pas grand-chose à Linux, mais voici le code C que j'ai écrit pour simuler d'énormes fichiers sur DC Share il y a de nombreuses années.

#include < stdio.h >
#include < stdlib.h >

int main() {
    int i;
    FILE *fp;

    fp=fopen("bigfakefile.txt","w");

    for(i=0;i<(1024*1024);i++) {
        fseek(fp,(1024*1024),SEEK_CUR);
        fprintf(fp,"C");
    }
}
Hippopotame gigantesque
la source
il doit y avoir de meilleures approches en C. Vous devez également fermer le fichier. Itération d'un million d'écriture 1 caractère à la fois ...
ACV
10

Vous pouvez également utiliser la commande "oui". La syntaxe est assez simple:

#yes >> myfile

Appuyez sur "Ctrl + C" pour arrêter cela, sinon il consommera tout votre espace disponible.

Pour nettoyer ce fichier, exécutez:

#>myfile

va nettoyer ce fichier.

Yogi
la source
7

Je ne pense pas que tu vas aller beaucoup plus vite que jj. Le goulot d'étranglement est le disque; y écrire des centaines de Go de données va prendre beaucoup de temps, peu importe comment vous le ferez.

Mais voici une possibilité qui pourrait fonctionner pour votre application. Si vous ne vous souciez pas du contenu du fichier, pourquoi ne pas créer un fichier "virtuel" dont le contenu est la sortie dynamique d'un programme? Au lieu d'ouvrir () le fichier, utilisez popen () pour ouvrir un canal vers un programme externe. Le programme externe génère des données chaque fois que cela est nécessaire. Une fois que le canal est ouvert, il agit exactement comme un fichier normal en ce sens que le programme qui a ouvert le canal peut fseek (), rembobiner (), etc. Vous devrez utiliser pclose () au lieu de close () lorsque vous êtes fait avec le tuyau.

Si votre application a besoin que le fichier soit d'une certaine taille, il appartiendra au programme externe de garder une trace de l'endroit où se trouve le "fichier" et d'envoyer un eof lorsque la "fin" sera atteinte.

Barry Brown
la source
4

Une approche: si vous pouvez garantir que les applications non liées n'utiliseront pas les fichiers de manière conflictuelle, créez simplement un pool de fichiers de tailles différentes dans un répertoire spécifique, puis créez des liens vers eux si nécessaire.

Par exemple, ayez un pool de fichiers appelé:

  • / accueil / bigfiles / 512M-A
  • / accueil / bigfiles / 512M-B
  • / accueil / bigfiles / 1024M-A
  • / accueil / bigfiles / 1024M-B

Ensuite, si vous avez une application qui a besoin d'un fichier 1G appelé / home / oracle / logfile, exécutez un " ln /home/bigfiles/1024M-A /home/oracle/logfile".

S'il s'agit d'un système de fichiers distinct, vous devrez utiliser un lien symbolique.

Les fichiers A / B / etc peuvent être utilisés pour garantir qu'il n'y a pas d'utilisation conflictuelle entre les applications non liées.

L'opération de liaison est à peu près aussi rapide que possible.

paxdiablo
la source
Vous pouvez avoir une petite piscine ou une grande piscine, c'est votre choix. De toute façon, vous alliez avoir besoin d'au moins un fichier, puisque c'est ce que l'interrogateur avait demandé. Si votre pool se compose d'un seul fichier, vous ne perdez rien. Si vous avez des bucketloads de disque (et vous devriez, étant donné son prix bas), il n'y a pas de problème.
paxdiablo
3

Le mkfile GPL est juste un wrapper de script (ba) sh autour de dd; Le fichier mkfile de BSD ne fait que définir un tampon avec une valeur non nulle et l'écrit à plusieurs reprises. Je ne m'attendrais pas à ce que l'ancien surpasse dd. Ce dernier peut légèrement dépasser dd si = / dev / zero car il omet les lectures, mais tout ce qui fait beaucoup mieux est probablement juste de créer un fichier clairsemé.

En l'absence d'un appel système qui alloue réellement de l'espace pour un fichier sans écrire de données (et Linux et BSD n'en ont pas, probablement Solaris également), vous pouvez obtenir une petite amélioration des performances en utilisant ftrunc (2) / truncate (1) pour étendre le fichier à la taille souhaitée, mappez le fichier en mémoire, puis écrivez des données non nulles dans les premiers octets de chaque bloc de disque (utilisez fgetconf pour trouver la taille du bloc de disque).

Alex Dupuy
la source
4
BSD et Linux ont en fait fallocate (edit: c'est maintenant POSIX et largement disponible).
Tobu
3

Plug sans vergogne: OTFFS fournit un système de fichiers fournissant des fichiers arbitrairement volumineux (enfin, presque. Exaoctets est la limite actuelle) du contenu généré. Il est uniquement Linux, en C simple et en début alpha.

Voir https://github.com/s5k6/otffs .

Stefan
la source
3

C'est le plus rapide que j'ai pu faire (ce qui n'est pas rapide) avec les contraintes suivantes:

  • Le but du gros fichier est de remplir un disque, il ne peut donc pas être compressé.
  • Utilisation du système de fichiers ext3. ( fallocatenon disponible)

C'est l'essentiel ...

// include stdlib.h, stdio.h, and stdint.h
int32_t buf[256]; // Block size.
for (int i = 0; i < 256; ++i)
{
    buf[i] = rand(); // random to be non-compressible.
}
FILE* file = fopen("/file/on/your/system", "wb");
int blocksToWrite = 1024 * 1024; // 1 GB
for (int i = 0; i < blocksToWrite; ++i)
{
   fwrite(buf, sizeof(int32_t), 256, file);
}

Dans notre cas, c'est pour un système Linux embarqué et cela fonctionne assez bien, mais préférerait quelque chose de plus rapide.

Pour info la commande dd if=/dev/urandom of=outputfile bs=1024 count = XXétait si lente qu'elle était inutilisable.

user79878
la source