Швидко створити великий файл у системі Linux


438

Як я можу швидко створити великий файл у системі Linux ( Red Hat Linux )?

dd зробить цю роботу, але читання /dev/zeroта запис на накопичувач може зайняти тривалий час, коли для тестування вам потрібен файл розміром у кілька сотень ГБ… Якщо вам потрібно це робити неодноразово, час дійсно збільшується.

Мене не хвилює вміст файлу, я просто хочу, щоб він був створений швидко. Як це можна зробити?

Використання розрідженого файлу для цього не допоможе. Мені потрібно, щоб файлу було виділено місце на диску.


1
У Ext4 є набагато краща продуктивність розподілу файлів, оскільки цілі блоки до 100 МБ можуть бути виділені відразу.
мартін

5
Команда 'усікати', до речі, створює розріджений файл. Наприклад, див. En.wikipedia.org/wiki/Sparse_file
Джейсон Дрю

2
Люди, здається, грубо ігнорують "розріджений файл із цим не працюватиме", а їхній скорочення і DD прагне нижче.
hpavc

1
Ви повинні були визначити, що ви мали на увазі під "тестуванням". Тестування швидкості запису вашого жорсткого диска? Тестуючи, що dfбуде повідомляти? Тестування програми, яка робить щось особливе. Відповідь залежить від того, що ви хочете перевірити. У всякому разі, я трохи запізнююся - зараз я бачу, що минуло років з часу вашого запитання :-)
ndemou

1
На всякий випадок, якщо ви шукаєте спосіб імітувати повний розділ, як я, не дивіться далі / dev / full
Julian

Відповіді:


509

ddз інших відповідей - це гарне рішення, але для цього це повільно. У Linux (та інших системах POSIX) у нас fallocate, який використовує потрібний простір без необхідності запису на нього, дуже швидко працює з більшістю сучасних дискових файлових систем:

Наприклад:

fallocate -l 10G gentoo_root.img

5
Чи можливо, що АД вже використовує це? Якщо я роблю 'dd, якщо = / dev / zero = zerofile bs = 1G count = 1' на ядрі 3.0.0, запис закінчується за 2 секунди, швидкість запису даних перевищує 500 мегабайт в секунду. Це однозначно неможливо на 2,5-
дюймовому

21
fallocateсаме те, що я шукав.
AB

7
Це ( fallocate) також не працюватиме на файлової системи Linux ZFS - github.com/zfsonlinux/zfs/issues/326
Джо

5
fallocate також не підтримується ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Едді

3
У Debian GNU / Linux fallocateє частиною util-linuxпакету. Цей інструмент написав Карел Зак з RedHat, а вихідний код можна знайти тут: kernel.org/pub/linux/utils/util-linux
Franta

295

Це поширене питання - особливо в сучасних умовах віртуального середовища. На жаль, відповідь не такий прямолінійний, як можна було б припустити.

dd - це очевидний перший вибір, але dd по суті є копією, і це змушує вас писати кожен блок даних (таким чином, ініціалізуючи вміст файлу) ... І саме ця ініціалізація займає стільки часу вводу / виводу. (Хочете, щоб це зайняло ще більше часу? Використовуйте / dev / random замість / dev / zero ! Тоді ви будете використовувати CPU, а також час вводу / виводу!) Зрештою, dd - це поганий вибір (хоча, по суті, за замовчуванням, використовуваний VM "create" GUI). Наприклад:

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

усікати - це ще один вибір - і, ймовірно, найшвидший ... Але це тому, що він створює "розріджений файл". По суті, розріджений файл - це ділянка диска, на якій є багато однакових даних, а основна файлова система "обманює", не дійсно зберігаючи всі дані, а просто "прикидаючись", що це все є. Таким чином, коли ви використовуєте скорочення для створення накопичувача на 20 ГБ для своєї віртуальної машини, файлова система насправді не виділяє 20 ГБ, але вона обманює і каже, що там є 20 ГБ нулів, навіть якщо на диску є лише одна доріжка може фактично (справді) бути у використанні. Наприклад:

 truncate -s 10G gentoo_root.img

fallocate є остаточним - і кращий - вибір для використання з виділенням диска VM, тому що вона по суті «резерви» (або «виділяє» все простору ви шукаєте, але це не заважає писати що - або так ,. коли ви використовуєте fallocate для створення віртуального накопичувача об'ємом 20 Гб, ви дійсно отримуєте файл 20 ГБ (не "розріджений файл", і вам не буде заважати писати на нього нічого - це означає, що практично все може бути в там - ніби абсолютно новий диск!) Наприклад:

fallocate -l 10G gentoo_root.img

4
+1 truncateфункціональний на JFS; fallocate, не так багато. Один момент: ви не можете включати десятковий номер у число, мені потрібно було вказати 1536G, ні 1.5T.
Кальріон

1
За моєю fallocateсторінці людини, це підтримується тільки btrfs, ext4, ocfs2і xfsфайлові системи
Nathan S. Watson-Хей

Примітка, swaponна жаль, не працює на попередньо виділених розширеннях, востаннє я перевірив. У списку розсилки XFS відбулася певна дискусія про те, щоб мати можливість помилкового викриття натомість старих даних про вільну простір і не мати розміру, позначеного як попередньо розміщений, тож обмін працює. Але я не думаю, що нічого не було зроблено.
Пітер Кордес

1
FYI, намагаючись прочитати занадто багато даних, /dev/randomможе призвести до вичерпання випадкових даних, і "Коли пул ентропії порожній, зчитування з / dev / random заблокується, поки не набереться додатковий екологічний шум", тому це може зайняти дуже дуже дуже тривалий час
Xen2050

154

Linux та всі файлові системи

xfs_mkfile 10240m 10Gigfile

Linux та деякі файлові системи (ext4, xfs, btrfs та ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS і, ймовірно, інші UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Пояснення

Спробуйте mkfile <size>мій файл як альтернативу dd. За допомогою -nпараметра відзначається розмір, але дискові блоки не виділяються, поки дані не будуть записані до них. Без -nопції простір заповнений нулем, що означає запис на диск, а це означає зайняття часу.

mkfile походить від SunOS і доступний не скрізь. У більшості систем Linux xfs_mkfileпрацює такий самий спосіб, але не тільки у файлових системах XFS, незважаючи на назву. Він включений до xfsprogs (для Debian / Ubuntu) або подібних названих пакетів.

У більшості систем Linux також є система fallocate, яка працює лише в певних файлових системах (таких як btrfs, ext4, ocfs2 та xfs), але це найшвидше, оскільки вона виділяє весь файловий простір (створює файли без холі), але не ініціалізує жодного з нього.


5
Де цей mkfile, про який ви говорите, незнайомець? Це не в установці RHEL за замовчуванням.
paxdiablo

2
Це утиліта solaris. якщо ви шукаєте gpl mkfile, ви знайдете кілька прикладів вихідного коду.
Мартін Бекетт

5
Працює як принадність для OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfileвходить у xfsprogs на Ubuntu і працює як шарм на моїх файлах ext3. :)
Грег Дубицький

97
truncate -s 10M output.file

створить файл 10 М миттєво (M означає 1024 * 1024 байт, MB - 1000 * 1000 - те саме, що K, KB, G, GB ...)

РЕДАКТИРУВАННЯ: як багато вказували, це фізично не виділить файл на вашому пристрої. За допомогою цього ви могли б насправді створити довільний великий файл, незалежно від наявного місця на пристрої, оскільки він створює "розріджений" файл.

Отже, виконуючи це, ви будете відкладати фізичне розподілення до доступу до файлу. Якщо ви збираєте цей файл в пам'ять, можливо, у вас не буде очікуваної продуктивності.

Але це все-таки корисна команда, яку потрібно знати


1
Спробував це, але це не впливає на доступний простір на диску. Потрібно, оскільки це розріджений файл, як описано раніше.
Gringo Suave

7
Це не повинно бути головною відповіддю, оскільки це не вирішує проблему, fallocateвідповідь наведена нижче.
Gringo Suave

4
@GringoSuave, але це все ще корисно для деяких людей, які можуть мати подібну, але трохи іншу проблему.
AJMansfield

@GringoSuave: Схоже, створюється великий файл за запитом, чому це не вирішує проблему? Також є відповіді на запитання, що в більшості випадків це навіть не працює.
Павло Шімерда

1
Навіщо пропонувати робити розріджені файли, коли він сказав, що це не буде працювати?
hpavc

44

Де шукаєте розмір потрібного файлу в байтах - 1.

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

6
Мені подобається такий підхід, але коментатор чомусь не хоче розрідженого файлу. :(
ефемія

3
dd, якщо = / dev / zero of = 1GBfile bs = 1000 count = 1000000
Damien

7
dd, якщо = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret

1
Для розріджених файлів, truncateздається, набагато краще.
Павло Шімерда

36

Приклади пошуку шукають розмір потрібного файлу в байтах

#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


З сторінки входу:

БЛОКИ та БЮТИ можуть супроводжуватися такими мультиплікаційними суфіксами: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024 і так далі для T, P, E, Z, Y.


Це виглядає набагато краще, ніж спосіб n-1 , тому він в основному еквівалентний truncate.
Павло Шімерда

19

Щоб створити файл 1 Гб:

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

7
Я вважаю, що підрахунок повинен бути 1. (випробуваний на центосах)
SvennD

dd if=/dev/zero of=filename bs=20G count=1створить лише 2 ГБ файл! не 20 Гб.
Maulik Gangani

18

Я не знаю багато про Linux, але ось код C, який я писав, щоб підробити величезні файли на DC Share багато років тому.

#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. Також потрібно закрити файл. Повторення мільйона, написання 1 символу одночасно ...
ACV

10

Ви також можете використовувати команду "так". Синтаксис досить простий:

#yes >> myfile

Натисніть "Ctrl + C", щоб зупинити це, інакше воно з'їсть весь ваш доступний простір.

Щоб очистити цей файл, запустіть:

#>myfile

очистить цей файл.


7

Я не думаю, що ви отримаєте набагато швидше, ніж дд. Вузьким місцем є диск; записування сотень ГБ даних для цього забирає багато часу, незалежно від того, як це робити.

Але ось вам може допомогти ваша програма. Якщо вам не байдуже вміст файлу, як щодо створення "віртуального" файлу, вміст якого є динамічним результатом програми? Замість відкриття файлу () використовуйте popen (), щоб відкрити трубку для зовнішньої програми. Зовнішня програма генерує дані, коли це потрібно. Щойно труба відкрита, вона діє як звичайний файл у тому, що програма, яка відкрила трубу, може переглядати (), перемотувати назад () тощо. Вам потрібно буде використовувати pclose () замість close (), коли ви зроблено з трубою.

Якщо вашій програмі потрібен файл певного розміру, за зовнішньою програмою слід буде відслідковувати, де у "файлі" він знаходиться, і надсилати eof, коли "кінець" досягнуто.


4

Один із підходів: якщо ви можете гарантувати, що не пов’язані програми не використовуватимуть файли конфліктним способом, просто створіть пул файлів різного розміру в певному каталозі, а потім створіть посилання на них за потреби.

Наприклад, мати пул файлів під назвою:

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

Потім, якщо у вас є програма, якій потрібен файл 1G під назвою / home / oracle / logfile, виконайте "ln /home/bigfiles/1024M-A /home/oracle/logfile ".

Якщо він знаходиться в окремій файловій системі, вам доведеться використовувати символічне посилання.

Файли A / B / etc можна використовувати для того, щоб не мати конфліктного використання між непов'язаними програмами.

Операція посилання проходить так само швидко, як ви можете отримати.


Ви можете мати невеликий басейн або великий басейн, це ваш вибір. Вам все одно знадобиться хоча б один файл, оскільки саме про це запитував запитувач. Якщо ваш пул складається з одного файлу, ви нічого не втрачаєте. Якщо у вас є завантаження диска (і вам слід, враховуючи його низьку ціну), немає жодних проблем.
paxdiablo

3

GPL mkfile - це лише (ba) sh обгортка сценарію навколо dd; Mkfile BSD просто запам'ятовує буфер з ненульовим значенням і записує його повторно. Я б не очікував, що колишній переможе дд. Останнє може трохи перевершити dd, якщо = / dev / zero, оскільки воно опускає читання, але все, що робить значно краще, ймовірно, просто створює розріджений файл.

Якщо немає системного виклику, який фактично виділяє простір для файлу без запису даних (а Linux і BSD цього не вистачає, можливо, і Solaris), ви можете отримати невелике поліпшення продуктивності, використовуючи ftrunc (2) / усікати (1) для розширення файлу до потрібного розміру mmap файл у пам'ять, а потім запишіть ненульові дані в перші байти кожного блоку диска (використовуйте fgetconf для пошуку розміру блоку диска).


4
Фактично BSD і Linux мають помилки (редагувати: зараз це POSIX і широко доступний).
Тобу

3

Безсоромний плагін: OTFFS забезпечує файлову систему, що забезпечує довільно великі (ну, майже. Exabytes - це поточний ліміт) файлів створеного вмісту. Це лише Linux, звичайний C, і на початку альфа.

Дивіться https://github.com/s5k6/otffs .


3

Це найшвидше, що я міг зробити (що не швидко) із такими обмеженнями:

  • Мета великого файлу - заповнити диск, тому його не можна стискати.
  • Використання файлової системи ext3 ( fallocateнедоступно)

У цьому суть ...

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

У нашому випадку це для вбудованої системи Linux, і це працює досить добре, але я б вважала за краще щось швидше.

FYI команда dd if=/dev/urandom of=outputfile bs=1024 count = XXбула настільки повільною, що була непридатною.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.