web-dev-qa-db-fra.com

Créer rapidement un fichier volumineux sur un système Linux

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

dd fera le travail, mais la lecture de /dev/zero et l'écriture sur le lecteur peuvent prendre du temps lorsque vous avez besoin d'un fichier de plusieurs centaines de Go pour le test ... Si vous avez besoin à faire cela à 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 fragmenté ne fonctionnera pas pour cela. J'ai besoin que le fichier soit alloué de l'espace disque.

391
DrStalker

dd parmi les autres réponses est une bonne solution, mais elle est lente pour cela. Sous Linux (et d'autres systèmes POSIX), nous avons fallocate, qui utilise l'espace souhaité sans l'écrire, fonctionne avec les systèmes de fichiers les plus modernes sur disque, très rapidement:

Par exemple:

fallocate -l 10G gentoo_root.img
461
Franta

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 croire.

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 beaucoup de temps d'entrée/sortie. (Vous voulez que cela prenne encore plus longtemps? Utilisez / dev/random au lieu de / dev/zero ! Ensuite, vous utiliserez le temps CPU ainsi que le temps d'E/S!) En fin de compte cependant, dd est un mauvais choix (bien qu’il s’agisse essentiellement de la valeur par défaut utilisée par les interfaces graphiques VM "create"). 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 fragmenté". Essentiellement, un fichier fragmenté est une section de disque qui contient beaucoup de données identiques. Le système de fichiers sous-jacent "triche" en ne stockant pas réellement toutes les données, mais en "prétendant" que tout y est. Ainsi, lorsque vous utilisez truncate pour créer un disque de 20 Go pour votre machine virtuelle, le système de fichiers n'alloue pas réellement 20 Go, mais il triche et indique qu'il y a 20 Go de zéros là-bas, même s'il ne reste qu'une piste sur le disque. peut effectivement (vraiment) être utilisé. Par exemple.:

 truncate -s 10G gentoo_root.img

fallocate est le final - et le meilleur - choix à utiliser avec VM allocation de disque, car il "réserve" (ou "alloue" tout l’espace recherché, mais il Ainsi, lorsque vous utilisez fallocate pour créer un espace de lecteur virtuel de 20 Go, vous obtenez réellement un fichier de 20 Go (et non un "fichier fragmenté", et vous n'aurez pas la peine d'écrire quoi que ce soit). c’est-à-dire qu’il pourrait y avoir pratiquement tout ce qu’il y a dedans - un peu comme un tout nouveau disque!)

fallocate -l 10G gentoo_root.img
279
Dan McAllister

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 au lieu de dd. Avec l'option _-n_, la taille est notée, mais les blocs de disque ne sont pas alloués jusqu'à ce que les données leur soient écrites. Sans l'option _-n_, l'espace est rempli à zéro, ce qui signifie que vous écrivez sur le disque, ce qui signifie qu'il faut du temps.

mkfile est dérivé de SunOS et n'est pas disponible partout. La plupart des systèmes Linux ont xfs_mkfile qui 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 des paquets nommés similaires.

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

138
CMS
truncate -s 10M output.file

créera un fichier 10 M instantanément (M correspond à 1024 * 1024 octets, MB à 1000 * 1000 - idem avec K, KB, G, GB, etc.)

EDIT: Comme beaucoup l'ont fait remarquer, 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 le périphérique, car il crée un fichier "fragmenté".

Ainsi, en procédant ainsi, vous différerez l’allocation physique jusqu’à ce que le fichier soit accessible. Si vous mappez ce fichier en mémoire, les performances escomptées risquent de ne pas être atteintes.

Mais cela reste une commande utile à connaître

92
kiv

Où seek est la taille du fichier que vous voulez en octets - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
42
Zoredache

Exemples où seek est la taille du fichier que vous voulez 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


De la page de manuel dd:

BLOCKS 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.

34
Sepero

Je ne connais pas beaucoup Linux, mais voici le code C que j’ai écrit pour simuler de gros 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");
    }
}
16
Humungous Hippo

Pour créer un fichier de 1 Go:

dd if=/dev/zero of=filename bs=1G count=1
14
max

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

#yes >> myfile

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

Pour nettoyer ce fichier, exécutez:

#>myfile

va nettoyer ce fichier.

8
Yogesh

Je ne pense pas que vous allez obtenir beaucoup plus vite que dd. Le goulot d'étranglement est le disque; L'écriture de centaines de Go de données sur cette opération prendra beaucoup de temps, peu importe comment vous le faites.

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 comme un fichier normal en ce sens que le programme qui a ouvert le canal peut utiliser fseek (), rewind (), etc. Vous devrez utiliser pclose () au lieu de close () lorsque vous êtes fait avec le tuyau.

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

5
Barry Brown

Une approche: si vous pouvez garantir que des applications non liées n'utiliseront pas les fichiers de manière conflictuelle, créez simplement un pool de fichiers de tailles variables dans un répertoire spécifique, puis créez des liens vers ceux-ci en cas de besoin.

Par exemple, avoir un pool de fichiers appelé:

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

Ensuite, si vous avez une application nécessitant un fichier 1G appelée/home/Oracle/logfile, exécutez un "ln /home/bigfiles/1024M-A /home/Oracle/logfile".

Si c'est sur un système de fichiers séparé, vous devrez utiliser un lien symbolique.

Les fichiers A/B/etc peuvent être utilisés pour éviter les conflits d’utilisation entre applications non liées.

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

3
paxdiablo

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

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

2
stefan

Le fichier GPL mk est juste un wrapper de script (ba) sh autour de dd; Le fichier mkfile de BSD memset simplement un tampon avec une valeur différente de zéro et l'écrit à plusieurs reprises. Je ne m'attendrais pas à ce que l'ancien soit plus performant que dd. Ce dernier peut délimiter légèrement dd if =/dev/zero car il omet les lectures, mais tout ce qui fait nettement mieux consiste probablement simplement à créer un fichier fragmenté.

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

2
Alex Dupuy

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

  • Le gros fichier a pour but de remplir un disque, il ne peut donc pas être compressé.
  • Utilisation du système de fichiers ext3. (fallocate non 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, il s’agit d’un système Linux embarqué et cela fonctionne assez bien, mais nous préférerions 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.

1
user79878