Bir Linux sisteminde hızlı bir şekilde büyük bir dosya oluşturun


438

Nasıl çabucakBir Linux ( Red Hat Linux ) sisteminde bir büyük bir dosya oluşturabilirim ?

gg işi yapacaktır, ancak /dev/zerotest için yüzlerce GB boyutunda bir dosyaya ihtiyacınız olduğunda sürücüden okuma ve sürücüye yazma uzun sürebilir ... Bunu tekrar tekrar yapmanız gerekiyorsa, zaman gerçekten eklenir.

Dosyanın içeriği umrumda değil, sadece hızlı bir şekilde oluşturulmasını istiyorum. Bu nasıl yapılabilir?

Seyrek bir dosya kullanmak bunun için çalışmaz. Disk alanı tahsis edilecek dosyaya ihtiyacım var.


1
Ext4 çok daha iyi dosya ayırma performansına sahiptir, çünkü 100MB'a kadar olan tüm bloklar aynı anda tahsis edilebilir.
martinus

5
'Truncate' komutu bu arada seyrek bir dosya oluşturur. Örneğin bkz. En.wikipedia.org/wiki/Sparse_file
Jason Drew

2
İnsanlar, "seyrek dosya bu işe yaramayacak" gibi büyük ölçüde görmezden geliyor gibi görünüyor.
hpavc

1
Ne demek istediğinizi "test etmek" için tanımlamış olmalısınız. Sabit diskinizin yazma hızını test etmek mi istiyorsunuz? Nelerin dfraporlanacağını test etmek ? Belirli bir şey yapan bir uygulamayı test etme. Cevap ne test etmek istediğinize bağlıdır. Her neyse biraz geç kaldım - şimdi sorunuzun üzerinden yıllar
geçtiğini görüyorum

1
Tam bir bölümü simüle etmenin bir yolunu aradığınızda, benim gibi, / dev /
Julian

Yanıtlar:


509

dddiğer cevaplardan iyi bir çözüm, ama bu amaç için yavaş. Linux'ta (ve diğer POSIX sistemlerinde), fallocateaslında üzerine yazmak zorunda kalmadan istenen alanı kullanan, en modern disk tabanlı dosya sistemleriyle çok hızlı çalışır:

Örneğin:

fallocate -l 10G gentoo_root.img

5
Dd'nin dahili olarak zaten kullanması mümkün mü? 3.0.0 çekirdeğinde = / dev / sıfır = sıfırdosyası bs = 1G sayısı = 1 'olursa, yazma işlemi saniyede 500 megabaytın üzerinde yazma veri hızı ile 2 saniyede biter. 2.5 "dizüstü bilgisayar sabit diskinde bu kesinlikle imkansız.
lxgr

21
fallocatetam olarak aradığım şeydi.
AB

7
Bu ( fallocate) aynı zamanda bir Linux ZFS dosya sisteminde de çalışmaz - github.com/zfsonlinux/zfs/issues/326
Joe

5
fallocate, ext3 tarafından da desteklenmez. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie

3
Debian GNU / Linux paketin bir fallocateparçasıdır util-linux. Bu araç RedHat'tan Karel Zak tarafından yazılmıştır ve kaynak kodu burada bulunabilir: kernel.org/pub/linux/utils/util-linux
Franta

295

Bu yaygın bir sorudur - özellikle günümüzün sanal ortamlarında. Ne yazık ki, cevap tahmin edebileceği kadar basit değildir.

dd bariz bir ilk tercihtir, ama dd aslında bir kopyadır ve sizi her veri bloğunu yazmaya zorlar (böylece dosya içeriğini başlatır) ... Ve bu başlatma çok fazla G / Ç süresi gerektiren şeydir. (Daha da uzun sürmesini ister misiniz? / Dev / zero yerine / dev / random kullanın ! Sonra CPU ve G / Ç zamanını kullanacaksınız!) Sonunda, dd kötü bir seçimdir (aslında VM "create" GUI'leri tarafından varsayılan olarak kullanılır). Örneğin:

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

truncate başka bir seçimdir - ve muhtemelen en hızlısıdır ... Ama bunun nedeni "seyrek bir dosya" yaratmasıdır. Esasen, seyrek bir dosya diskin aynı veriye sahip bir bölümüdür ve temel dosya sistemi tüm verileri gerçekten depolamakla kalmaz, sadece orada olduğunu iddia ederek "aldatır". Bu nedenle, VM'niz için 20 GB'lık bir sürücü oluşturmak için kesmeyi kullandığınızda, dosya sistemi aslında 20 GB tahsis etmez, ancak hile yapar ve diskte bir parça kadar az olsa bile 20 GB sıfır olduğunu söyler aslında (gerçekten) kullanımda olabilir. Örneğin:

 truncate -s 10G gentoo_root.img

fallocate nihai - ve en iyisi - seçim . aslında "rezervleri" (veya boşluk Sen arayan tüm "ayırır", ancak Yani yazma şey rahatsız etmez, çünkü VM diski tahsisi ile kullanım için 20 GB'lık bir sanal sürücü alanı oluşturmak için fallocate kullandığınızda, gerçekten 20 GB'lık bir dosya elde edersiniz ("seyrek bir dosya" değil) ve herhangi bir şey yazmak için uğraşmazsınız - yani neredeyse her şey olabilir orada - yeni bir disk gibi!) Örneğin:

fallocate -l 10G gentoo_root.img

4
+1 truncate, JFS'de işlevseldir; fallocate, çok değil. Bir nokta: Sayıya bir ondalık sayı ekleyemezsiniz, belirtmem gerekiyordu 1536G, değil 1.5T.
Calrion

1
Benim göre fallocateadam sayfasında, bu sadece desteklenir btrfs, ext4, ocfs2, ve xfsdosya sistemleri
Nathan S. Watson-Haigh

Not swaponmaalesef önceden ayrılmış kapsamları üzerinde çalışmaya değil, son kontrol ettim. XFS posta listesinde, eski serbest alan verilerini ortaya çıkarmak için yanlış bir seçeneğe sahip olma ve önceden yerleştirilmiş olarak işaretlenmemiş bir dereceye sahip olmama konusunda bazı tartışmalar yapıldı, bu yüzden swapon işe yarayacaktı. Ama hiçbir şey yapıldığını sanmıyorum.
Peter Cordes

1
FYI, çok fazla veri okumaya /dev/randomçalışmak rastgele verilerin tükenmesine neden olabilir ve "Entropi havuzu boş olduğunda, / dev / random'dan gelen okumalar ek çevresel gürültü toplanana kadar engellenir", bu yüzden çok çok uzun zaman
Xen2050

154

Linux ve tüm dosya sistemleri

xfs_mkfile 10240m 10Gigfile

Linux ve bazı dosya sistemleri (ext4, xfs, btrfs ve ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS ve muhtemelen diğer UNIX'ler

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

açıklama

mkfile <size>Dosyamı alternatif olarak deneyin dd. İle -nseçeneği boyutu not edilir, ancak veri onlara yazılır kadar disk blokları tahsis edilmez. -nSeçenek olmadan, alan sıfır doldurulur, bu da diske yazmak anlamına gelir, bu da zaman almak anlamına gelir.

mkfile SunOS'tan türetilmiştir ve her yerde mevcut değildir. Çoğu Linux sistemi xfs_mkfile, isme rağmen sadece XFS dosya sistemlerinde değil, aynı şekilde çalışır. Bu dahildir? Xfsprogs (Debian / Ubuntu için) veya benzer isimli paketler.

Çoğu Linux sistemi de fallocatesadece belirli dosya sistemlerinde (btrfs, ext4, ocfs2 ve xfs gibi) çalışır, ancak en hızlı olanıdır, çünkü tüm dosya alanını ayırır (holey olmayan dosyalar oluşturur) ancak herhangi bir başlatmaz. onun.


5
Konuştuğun bu mkfile nerede, yabancı? Varsayılan RHEL kurulumunda değil.
paxdiablo

2
Bir solaris yardımcı programıdır. gpl mkfile için arama yaparsanız bazı kaynak kodu örnekleri bulacaksınız.
Martin Beckett

5
OS X'de bir charme olarak çalışır:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfileUbuntu'daki xfsprogs'a dahil edildi ve benim ext3 fs'de bir cazibe gibi çalışıyor. :)
Greg Dubicki

97
truncate -s 10M output.file

anında 10 M dosya oluşturur (M 1024 * 1024 bayt, MB 1000 * 1000 anlamına gelir - K, KB, G, GB ile aynıdır ...)

DÜZENLE: birçok kişinin belirttiği gibi, bu dosyayı fiziksel olarak cihazınıza ayırmaz. Bununla, "seyrek" bir dosya oluşturduğundan, cihazdaki kullanılabilir alandan bağımsız olarak rastgele büyük bir dosya oluşturabilirsiniz.

Böylece, bunu yaparken dosyaya erişilene kadar fiziksel ayırmayı ertelersiniz. Bu dosyayı bellekle eşliyorsanız, beklenen performansınız olmayabilir.

Ama bu hala bilmek için yararlı bir komut


1
Bunu denedim, ancak kullanılabilir disk alanını etkilemez. Daha önce açıklandığı gibi seyrek bir dosya olması gerekir.
Gringo Suave

7
Sorunu çözmediği için bu en iyi cevap olmamalı, aşağıdaki fallocatecevap.
Gringo Suave

4
@GringoSuave ancak bu, benzer ama biraz farklı bir sorunu olan bazı insanlar için hala yararlıdır.
AJMansfield

@GringoSuave: İstendiği gibi büyük bir dosya oluşturuyor gibi görünüyor, neden sorunu çözmüyor? Ayrıca yanlış cevap altında çoğu durumda bile işe yaramadığı notları vardır.
Pavel Šimerda

1
Neden işe yaramayacağını söylediğinde seyrek dosyalar yapmayı öneriyorsunuz?
hpavc

44

Arama, bayt olarak istediğiniz dosyanın boyutu - 1.

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

6
Bu yaklaşımı seviyorum, ancak yorumcu bir nedenden dolayı seyrek bir dosya istemiyor. :(
ephemient

3
gg = = dev / sıfır = 1 GB dosya bs = 1000 sayım = 1000000
Damien

7
gg = = dev / sıfır = 01 GBdosya bs = 1024 sayımı = $ ((1024 * 1024))
Xavier Decoret

1
Seyrek dosyalar truncateiçin çok daha iyi görünüyor.
Pavel Šimerda

36

Aramanın, bayt olarak istediğiniz dosyanın boyutu olduğu örnekler

#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


Dd kılavuzundan:

BLOKLARI ve BYTES'i şu çarpım ekleri izleyebilir: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * T, P, E, Z, Y için 1000, G = 1024 * 1024 * 1024 vb.


Bu n-1 yolundan çok daha iyi görünüyor , bu yüzden temel olarak eşdeğer truncate.
Pavel Šimerda

19

1 GB dosya oluşturmak için:

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

7
Sayının 1 olması gerektiğine inanıyorum. (Centos üzerinde test edildi)
SvennD

dd if=/dev/zero of=filename bs=20G count=1sadece 2GB dosya oluşturacak! 20GB değil.
Maulik Gangani

18

Linux hakkında pek bir şey bilmiyorum, ama işte yıllar önce DC Share'de büyük dosyaları sahte yazmak için yazdığım C Kodu.

#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");
    }
}

C'de daha iyi yaklaşımlar olmalıdır. Ayrıca dosyayı kapatmanız gerekir. Tek seferde bir milyon yazma karakterine yineleme ...
ACV

10

"Evet" komutunu da kullanabilirsiniz. Sözdizimi oldukça basittir:

#yes >> myfile

Bunu durdurmak için "Ctrl + C" tuşlarına basın, aksi takdirde mevcut tüm alanınızı yiyecektir.

Bu dosyayı temizlemek için çalıştırın:

#>myfile

bu dosyayı temizleyecektir.


7

DD'den çok daha hızlı olacağınızı sanmıyorum. Darboğaz disktir; yüzlerce GB veri yazmak nasıl yaparsanız yapın çok uzun zaman alacaktır.

Ancak burada uygulamanız için işe yarayabilecek bir olasılık var. Dosyanın içeriğiyle ilgilenmezseniz, içeriği bir programın dinamik çıktısı olan bir "sanal" dosya oluşturmaya ne dersiniz? Dosyayı açmak () yerine, harici bir programa kanal açmak için popen () kullanın. Harici program gerektiğinde veri üretir. Boru açıldıktan sonra, boruyu açan programın fseek (), geri sarma () vb. Yapabileceği normal bir dosya gibi davranır. boru ile yapılır.

Uygulamanızın belirli bir boyutta olması gerekiyorsa, "dosya" nın nerede olduğunu takip etmek ve "sona" ulaşıldığında bir eof göndermek harici programa bağlıdır.


4

Tek bir yaklaşım: ilgisiz uygulamaların dosyaları çelişkili bir şekilde kullanmayacağını garanti ediyorsanız, belirli bir dizinde değişen boyutlarda bir dosya havuzu oluşturun, ardından gerektiğinde bunlara bağlantılar oluşturun.

Örneğin, şu adda bir dosya havuzuna sahip olun:

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

Ardından, / home / oracle / logfile adında bir 1G dosyasına ihtiyaç duyan bir uygulamanız varsa, bir " ln /home/bigfiles/1024M-A /home/oracle/logfile" yürütün .

Ayrı bir dosya sisteminde ise, sembolik bir bağlantı kullanmanız gerekir.

A / B / etc dosyaları, ilgisiz uygulamalar arasında çakışan kullanım olmadığından emin olmak için kullanılabilir.

Bağlantı işlemi, alabileceğiniz kadar hızlıdır.


Küçük bir havuz veya büyük bir havuz olabilir, seçim sizin. Zaten en az bir dosyaya ihtiyacınız olacaktı, çünkü soru soran budur. Havuzunuz bir dosyadan oluşuyorsa hiçbir şey kaybetmezsiniz. Kepçeli diskleriniz varsa (ve düşük fiyatı göz önüne alındığında), sorun yoktur.
paxdiablo

3

GPL mkfile dd etrafında sadece bir (ba) sh komut dosyası sarıcıdır; BSD'nin mkfile değeri sıfır olmayan bir tamponu takar ve tekrar tekrar yazar. Ben eski dd gerçekleştirmek için beklemem. İkincisi = / dev / zero eğer okumaları atladığı için dd'yi hafifçe dışlayabilir, ancak önemli ölçüde daha iyi olan her şey muhtemelen seyrek bir dosya oluşturmaktır.

Veri yazmadan bir dosya için yer ayıran bir sistem çağrısı yoksa (ve Linux ve BSD'de bu eksiklik, muhtemelen Solaris de), dosyayı genişletmek için ftrunc (2) / truncate (1) kullanarak performansta küçük bir gelişme elde edebilirsiniz. İstediğiniz boyuta getirin, dosyayı belleğe eşleyin, ardından her disk bloğunun ilk baytına sıfır olmayan veri yazın (disk bloğu boyutunu bulmak için fgetconf kullanın).


4
BSD ve Linux aslında yanlıştır (düzenle: şimdi POSIX ve yaygın olarak kullanılabilir).
Tobu

3

Utanmaz fiş: OTFFS, oluşturulan içeriğin gelişigüzel büyüklükte (neredeyse, Exabytes geçerli sınırdır) dosyaları sağlayan bir dosya sistemi sağlar. Yalnızca Linux, düz C ve erken alfadadır.

Bkz. Https://github.com/s5k6/otffs .


3

Bu, aşağıdaki kısıtlamalarla yapabileceğim en hızlı ( hızlı değil ):

  • Büyük dosyanın amacı bir diski doldurmaktır, bu yüzden sıkıştırılamaz.
  • Ext3 dosya sistemini kullanma. ( fallocatemevcut değil)

Bu onun özü ...

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

Bizim durumumuzda bu gömülü bir linux sistemi içindir ve bu yeterince iyi çalışır, ancak daha hızlı bir şey tercih eder.

FYI komutu dd if=/dev/urandom of=outputfile bs=1024 count = XXkullanılamayacak kadar yavaştı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.