Buat file besar dengan cepat di sistem Linux

438

Bagaimana saya dapat dengan cepat membuat file besar di sistem Linux ( Red Hat Linux )?

dd akan melakukan pekerjaan itu, tetapi membaca dari /dev/zerodan menulis ke drive bisa memakan waktu lama ketika Anda membutuhkan file beberapa ratus GB dalam ukuran untuk pengujian ... Jika Anda perlu melakukannya berulang kali, waktu benar-benar bertambah.

Saya tidak peduli tentang isi file, saya hanya ingin itu dibuat dengan cepat. Bagaimana ini bisa dilakukan?

Menggunakan file jarang tidak akan berfungsi untuk ini. Saya perlu file tersebut dialokasikan ruang disk.

DrStalker
sumber
1
Ext4 memiliki kinerja alokasi file yang jauh lebih baik, karena seluruh blok hingga 100MB dapat dialokasikan sekaligus.
martinus
5
Omong-omong, perintah 'truncate' membuat file jarang. Misalnya, lihat en.wikipedia.org/wiki/Sparse_file
Jason Drew
2
Orang-orang tampaknya sangat mengabaikan "file jarang tidak akan bekerja dengan ini", dengan memotong dan mencari mereka di bawah ini.
hpavc
1
Anda harus mendefinisikan apa yang Anda maksud dengan "untuk pengujian". Menguji kecepatan penulisan hard disk Anda? Menguji apa yang dfakan dilaporkan? Menguji aplikasi yang melakukan sesuatu yang khusus. Jawabannya tergantung pada apa yang ingin Anda uji. Pokoknya saya agak terlambat - saya mengerti sekarang sudah bertahun-tahun sejak pertanyaan Anda :-)
ndemou
1
Jika Anda mencari cara untuk mensimulasikan partisi penuh, seperti saya, tidak terlihat lagi dari / dev / full
Julian

Jawaban:

509

dddari jawaban lain adalah solusi yang baik, tetapi lambat untuk tujuan ini. Di Linux (dan sistem POSIX lainnya), kami memiliki fallocate, yang menggunakan ruang yang diinginkan tanpa harus benar-benar menulisnya, bekerja dengan sebagian besar sistem file berbasis disk modern, sangat cepat:

Sebagai contoh:

fallocate -l 10G gentoo_root.img
Franta
sumber
5
Apakah mungkin dd sudah menggunakannya secara internal? Jika saya melakukan dd jika = / dev / nol = zerofile bs = 1G hitung = 1 'pada kernel 3.0.0, penulisan selesai dalam 2 detik, dengan kecepatan data tulis lebih dari 500 megabyte per detik. Itu jelas tidak mungkin pada harddisk laptop 2,5 ".
lxgr
21
fallocatepersis apa yang saya cari.
AB
7
Ini ( fallocate) juga tidak akan berfungsi pada sistem file Linux ZFS - github.com/zfsonlinux/zfs/issues/326
Joe
5
fallocate juga tidak didukung oleh ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie
3
Dalam Debian GNU / Linux fallocateadalah bagian dari util-linuxpaket. Alat ini ditulis oleh Karel Zak dari RedHat dan kode sumber dapat ditemukan di sini: kernel.org/pub/linux/utils/util-linux
Franta
295

Ini adalah pertanyaan umum - terutama di lingkungan lingkungan virtual saat ini. Sayangnya, jawabannya tidak semudah yang diperkirakan.

dd adalah pilihan pertama yang jelas, tetapi dd pada dasarnya adalah salinan dan yang memaksa Anda untuk menulis setiap blok data (dengan demikian, menginisialisasi isi file) ... Dan inisialisasi itulah yang memakan banyak waktu I / O. (Ingin membuatnya lebih lama? Gunakan / dev / acak bukan / dev / nol ! Maka Anda akan menggunakan CPU serta waktu I / O!) Pada akhirnya, dd adalah pilihan yang buruk (meskipun pada dasarnya standar yang digunakan oleh VM "buat" GUI). Misalnya:

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

truncate adalah pilihan lain - dan mungkin yang tercepat ... Tapi itu karena ia membuat "file jarang". Pada dasarnya, file jarang adalah bagian dari disk yang memiliki banyak data yang sama, dan sistem file yang mendasarinya "menipu" dengan tidak benar-benar menyimpan semua data, tetapi hanya "berpura-pura" bahwa semua ada di sana. Jadi, ketika Anda menggunakan truncate untuk membuat drive 20 GB untuk VM Anda, filesystem tidak benar-benar mengalokasikan 20 GB, tetapi itu menipu dan mengatakan bahwa ada 20 GB nol di sana, meskipun hanya satu track pada disk. sebenarnya (benar-benar) sedang digunakan. Misalnya:

 truncate -s 10G gentoo_root.img

fallocate adalah akhir - dan terbaik - pilihan untuk digunakan dengan alokasi disk yang VM, karena pada dasarnya "cadangan" (atau "mengalokasikan" semua ruang Anda sedang mencari, tetapi tidak repot-repot untuk menulis apa-apa Jadi,. ketika Anda menggunakan fallocate untuk membuat ruang drive virtual 20 GB, Anda benar-benar mendapatkan file 20 GB (bukan "file jarang", dan Anda tidak akan repot-repot menulis apa pun untuk itu - yang berarti hampir apa pun bisa berada di sana - jenis seperti disk baru!) Mis:

fallocate -l 10G gentoo_root.img
Dan McAllister
sumber
4
+1 truncateberfungsi pada JFS; fallocate, tidak terlalu banyak. Satu poin: Anda tidak dapat memasukkan desimal dalam angka, saya harus menentukan 1536G, bukan 1.5T.
Calrion
1
Menurut saya fallocatehalaman manual, ini hanya didukung pada btrfs, ext4, ocfs2, dan xfsfilesystem
Nathan S. Watson-Haigh
Catatan swaponsayangnya tidak bekerja pada luasan yang dialokasikan sebelumnya, terakhir saya periksa. Ada beberapa diskusi di milis XFS tentang memiliki opsi fallocate untuk mengekspos data freespace lama sebagai gantinya dan tidak memiliki batas yang ditandai preallocated, sehingga swapon akan berfungsi. Tapi saya tidak berpikir ada yang pernah dilakukan.
Peter Cordes
1
FYI, mencoba membaca terlalu banyak data dari /dev/randomdapat mengakibatkan kehabisan data acak, dan "Ketika kumpulan entropi kosong, pembacaan dari / dev / acak akan memblokir sampai kebisingan lingkungan tambahan dikumpulkan" sehingga bisa mengambil sangat sangat sangat lama
Xen2050
154

Linux & semua sistem file

xfs_mkfile 10240m 10Gigfile

Linux & dan beberapa sistem file (ext4, xfs, btrfs dan ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS dan mungkin UNIX lainnya

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Penjelasan

Coba mkfile <size>myfile sebagai alternatif dd. Dengan -nopsi ukuran dicatat, tetapi blok disk tidak dialokasikan sampai data ditulis kepada mereka. Tanpa -nopsi, ruang kosong, yang berarti menulis ke disk, yang berarti membutuhkan waktu.

mkfile berasal dari SunOS dan tidak tersedia di mana-mana. Sebagian besar sistem Linux memiliki cara xfs_mkfileyang persis sama, dan tidak hanya pada sistem file XFS meskipun namanya. Ini termasuk dalam xfsprogs (untuk Debian / Ubuntu) atau paket bernama serupa.

Sebagian besar sistem Linux juga memiliki fallocate, yang hanya bekerja pada sistem file tertentu (seperti btrfs, ext4, ocfs2, dan xfs), tetapi merupakan yang tercepat, karena ia mengalokasikan semua ruang file (membuat file non-berlubang) tetapi tidak menginisialisasi semua itu.

CMS
sumber
5
Di mana mkfile yang kamu bicarakan ini, orang asing? Itu tidak ada dalam pemasangan RHEL default.
paxdiablo
2
Ini adalah utilitas solaris. jika Anda mencari gpl mkfile Anda akan menemukan beberapa contoh kode sumber.
Martin Beckett
5
Berfungsi sebagai pesona pada OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose
2
xfs_mkfiletermasuk dalam xfsprogs di Ubuntu dan berfungsi seperti mantra pada ext3 fs saya. :)
Greg Dubicki
97
truncate -s 10M output.file

akan membuat file 10 M secara instan (M berarti 1024 * 1024 byte, MB berarti 1000 * 1000 - sama dengan K, KB, G, GB ...)

EDIT: seperti yang telah ditunjukkan banyak orang, ini tidak akan secara fisik mengalokasikan file pada perangkat Anda. Dengan ini, Anda benar-benar dapat membuat file besar sembarang, terlepas dari ruang yang tersedia pada perangkat, karena itu membuat file "jarang".

Jadi, ketika melakukan ini, Anda akan menunda alokasi fisik hingga file diakses. Jika Anda memetakan file ini ke memori, Anda mungkin tidak memiliki kinerja yang diharapkan.

Tapi ini masih perintah yang berguna untuk diketahui

kiv
sumber
1
Sudah mencoba ini, tetapi tidak mempengaruhi ruang disk yang tersedia. Harus karena ini adalah file yang jarang seperti yang dijelaskan sebelumnya.
Gringo Suave
7
Ini seharusnya bukan jawaban atas karena tidak menyelesaikan masalah, fallocatejawabannya di bawah ini.
Gringo Suave
4
@GringoSuave tetapi ini masih berguna untuk beberapa orang yang mungkin memiliki masalah yang serupa tapi sedikit berbeda.
AJMansfield
@ GringoSuave: Tampaknya membuat file besar seperti yang diminta, mengapa tidak menyelesaikan masalah? Juga ada catatan di bawah jawaban fallocate yang bahkan tidak berfungsi pada kebanyakan kasus.
Pavel Šimerda
1
Mengapa menyarankan membuat file jarang ketika dia mengatakan itu tidak akan berhasil?
hpavc
44

Di mana seek adalah ukuran file yang Anda inginkan dalam bytes - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Sakit kepala
sumber
6
Saya suka pendekatan ini, tetapi komentator tidak ingin file jarang karena beberapa alasan. :(
ephemient
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
Untuk file yang jarang, truncatesepertinya jauh lebih baik.
Pavel Šimerda
36

Contoh di mana mencari adalah ukuran file yang Anda inginkan dalam byte

#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


Dari halaman dd:

BLOK dan BANTUAN dapat diikuti oleh sufiks multiplikasi berikut: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024, dan seterusnya untuk T, P, E, Z, Y.

Sepero
sumber
Ini terlihat jauh lebih baik daripada cara n-1 , jadi pada dasarnya setara dengan truncate.
Pavel Šimerda
19

Untuk membuat file 1 GB:

dd if=/dev/zero of=filename bs=1G count=1
maks
sumber
7
Saya percaya hitungan harus 1. (diuji pada centos)
SvennD
dd if=/dev/zero of=filename bs=20G count=1hanya akan membuat file 2GB! bukan 20GB.
Maulik Gangani
18

Saya tidak tahu banyak tentang Linux, tapi ini C Code yang saya tulis untuk memalsukan file besar di DC Share bertahun-tahun yang lalu.

#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");
    }
}
Kuda Nil yang humungous
sumber
harus ada pendekatan yang lebih baik dalam C. Anda juga harus menutup file. Iterating ke satu juta menulis 1 char pada suatu waktu ...
ACV
10

Anda dapat menggunakan perintah "ya" juga. Sintaksnya cukup sederhana:

#yes >> myfile

Tekan "Ctrl + C" untuk menghentikan ini, jika tidak maka akan memakan semua ruang Anda yang tersedia.

Untuk membersihkan file ini jalankan:

#>myfile

akan membersihkan file ini.

Yogi
sumber
7

Saya tidak berpikir Anda akan mendapatkan lebih cepat daripada dd. Hambatannya adalah disk; menulis ratusan GB data untuk itu akan memakan waktu lama tidak peduli bagaimana Anda melakukannya.

Tapi di sini ada kemungkinan yang bisa digunakan untuk aplikasi Anda. Jika Anda tidak peduli dengan isi file, bagaimana dengan membuat file "virtual" yang isinya merupakan output dinamis dari suatu program? Alih-alih membuka () file, gunakan popen () untuk membuka pipa ke program eksternal. Program eksternal menghasilkan data kapan pun dibutuhkan. Setelah pipa terbuka, ini berfungsi seperti file biasa karena program yang membuka pipa dapat fseek (), mundur (), dll. Anda harus menggunakan pclose () alih-alih menutup () ketika Anda dilakukan dengan pipa.

Jika aplikasi Anda membutuhkan file dengan ukuran tertentu, itu akan tergantung pada program eksternal untuk melacak di mana di "file" itu dan mengirimkan bukti ketika "end" telah tercapai.

Barry Brown
sumber
4

Satu pendekatan: jika Anda dapat menjamin aplikasi yang tidak terkait tidak akan menggunakan file dengan cara yang bertentangan, buat saja kumpulan file dengan ukuran yang berbeda-beda di direktori tertentu, lalu buat tautan ke sana jika diperlukan.

Misalnya, minta kumpulan file yang disebut:

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

Kemudian, jika Anda memiliki aplikasi yang membutuhkan file 1G bernama / home / oracle / logfile, jalankan " ln /home/bigfiles/1024M-A /home/oracle/logfile".

Jika ada pada sistem file yang terpisah, Anda harus menggunakan tautan simbolik.

File A / B / etc dapat digunakan untuk memastikan tidak ada penggunaan yang saling bertentangan antara aplikasi yang tidak terkait.

Operasi tautan hampir secepat yang Anda bisa.

paxdiablo
sumber
Anda dapat memiliki kolam kecil atau kolam besar, itu pilihan Anda. Anda akan memerlukan setidaknya satu file, karena itulah yang diminta si penanya. Jika kumpulan Anda terdiri dari satu file, Anda tidak kehilangan apa-apa. Jika Anda memiliki banyak disk (dan Anda harus, mengingat harganya yang murah), tidak ada masalah.
paxdiablo
3

GPL mkfile hanyalah pembungkus skrip (ba) di sekitar dd; Mkfile BSD hanya memsets buffer dengan non-zero dan menulisnya berulang kali. Saya tidak akan mengharapkan mantan untuk melakukan dd. Yang terakhir mungkin lebih baik dd jika = / dev / nol sedikit karena menghilangkan membaca, tetapi apa pun yang secara signifikan lebih baik mungkin hanya membuat file jarang.

Tidak ada panggilan sistem yang benar-benar mengalokasikan ruang untuk file tanpa menulis data (dan Linux dan BSD tidak memilikinya, mungkin Solaris juga) Anda mungkin mendapatkan sedikit peningkatan dalam kinerja dengan menggunakan ftrunc (2) / truncate (1) untuk memperpanjang file ke ukuran yang diinginkan, mmap file ke dalam memori, kemudian tulis data bukan nol ke byte pertama dari setiap blok disk (gunakan fgetconf untuk menemukan ukuran blok disk).

Alex Dupuy
sumber
4
BSD dan Linux sebenarnya memiliki fallocate (edit: sekarang POSIX dan tersedia secara luas).
Tobu
3

Steker tak tahu malu: OTFFS menyediakan sistem file yang menyediakan file besar yang sewenang-wenang (well, hampir. Exabytes adalah batas saat ini) dari konten yang dihasilkan. Ini hanya Linux, C biasa, dan dalam alpha awal.

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

Stefan
sumber
3

Ini adalah yang tercepat yang bisa saya lakukan (yang tidak cepat) dengan batasan-batasan berikut:

  • Tujuan dari file besar adalah untuk mengisi disk, jadi tidak dapat dikompres.
  • Menggunakan sistem file ext3. ( fallocatetidak tersedia)

Ini adalah intinya ...

// 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);
}

Dalam kasus kami, ini untuk sistem linux tertanam dan ini berfungsi cukup baik, tetapi lebih suka sesuatu yang lebih cepat.

FYI perintahnya dd if=/dev/urandom of=outputfile bs=1024 count = XXsangat lambat sehingga tidak bisa digunakan.

pengguna79878
sumber