C на amd64 Linux, 36 байт (тільки часова мітка), 52 49 байт (реальна дискова активність)
Я жорстко open(2)кодую прапори, тому це не переноситься для інших ABI. Linux на інших платформах, ймовірно, використовує те саме O_TRUNCі т.д., але інші POSIX ОС можуть не використовувати.
+4 байти, щоб передати правильний аргумент дозволу, щоб переконатися, що файл створений з доступом до запису власника, див. Нижче. (Це трапляється для роботи з gcc 5.2)
кілька портативний ANSI C, 38/51 байт (лише часова мітка), 52/67 байт (реальна активність диска)
На основі відповіді @ Cat, з підказкою від @Jens.
Перше число - це для реалізацій, де intможе містити FILE *fopen()зворотне значення, друге - якщо ми не можемо цього зробити. В Linux, купи купи містяться в 32 бітах адресного простору, тому він працює навіть без -m32або -mx32. (Декларування void*fopen();коротше #include <stdio.h>)
Тільки метадані вводу / виводу часових міток :
main(){for(;;)close(open("a",577));} // Linux x86-64
//void*fopen(); // compile with -m32 or -mx32 or whatever, so an int holds a pointer.
main(){for(;;)fclose(fopen("a","w"));}
Написання байтів, фактично потрапляючи на диск на Linux 4.2.0 + XFS + lazytime:
main(){for(;write(open("a",577),"",1);close(3));}
writeє умовою for-циклу, що добре, оскільки вона завжди повертає 1. closeце приріст.
// semi-portable: storing a FILE* in an int. Works on many systems
main(f){for(;f=fopen("a","w");fclose(f))fputc(0,f);} // 52 bytes
// Should be highly portable, except to systems that require prototypes for all functions.
void*f,*fopen();main(){for(;f=fopen("a","w");fclose(f))fputc(0,f);} // 67 bytes
Пояснення не портативної версії:
Файл створюється з випадковими дозволами сміття. З gcc5.2, з -O0або -O3, трапляється включити дозвіл на запис власника, але це не гарантується. 0666- десятковий 438. Третій аргумент openзайме ще 4 байти . Ми вже жорстко кодуємо O_TRUNC і так далі, але це може зламатися з іншим компілятором або libc на тому ж ABI.
Ми не можемо опустити другий аргумент open, тому що значення сміття включає O_EXCL, і O_TRUNC|O_APPEND, таким чином, відкриті не вдається EINVAL.
Нам не потрібно зберігати повернене значення від open(). Ми припускаємо, що так 3, тому що це завжди буде. Навіть якщо ми почнемо з fd 3 open, він буде закритий після першої ітерації. Найгірше - він openвідкриває нові FDS, поки 3 не буде останнім доступним дескриптором файлів. Отже, до перших 65531 write()дзвінків може не вдатися EBADF, але тоді вони працюватимуть нормально при кожному openстворенні fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNCв Linux x86-64. Без цього O_TRUNC, час модифікації inode та час зміни не оновлюються, тому коротший аргумент неможливий. O_TRUNCє все ще важливим для версії, яка дзвонитьwrite виробляти фактичну активність диска, а не переписувати на місці.
Я бачу деякі відповіді на це open("a",1). O_CREAT потрібен, якщо aвін ще не існує. O_CREATвизначається як восьмеричний 0100 (64, 0x40) в Linux.
Жоден ресурс не протікає, тому він може працювати назавжди. straceвихід:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
або
open("a", O_WRONLY|O_CREAT|O_TRUNC, 01) = 3
write(3, "\0", 1) = 1 # This is the terminating 0 byte in the empty string we pass to write(2)
close(3) = 0
Я отримав десяткове значення openпрапорців для цього ABI, використовуючи strace -eraw=openмою версію C ++.
У файловій системі з lazytimeувімкненою опцією кріплення Linux зміна, яка впливає лише на часові позначки inode, спричинить лише одне записування протягом 24 годин. Якщо ця опція монтажу відключена, оновлення часових позначок може бути корисним способом зносу вашого SSD. (Однак кілька інших відповідей мають лише метадані I / O).
альтернативи:
коротший непрацюючий :
main(){for(;;)close(write(open("a",577),"",3));}використовує writeповернене значення для передачі 3аргументу на закриття. Він зберігає інший байт, але не працює з gcc -O0 або -O3 на amd64. Сміття в третьому аргументі openвідрізняється, і не містить дозволу на запис. aстворюється вперше, але майбутні ітерації не вдається -EACCESS.
довше, працюючи, з різними системними дзвінками :
main(c){for(open("a",65);pwrite(3,"",1);)sync();} переписує байт на місці і дзвонить sync() синхронізувати всі файлові системи в масштабах усієї системи. Це засвічує світло приводу.
Нам не байдуже, який байт, тому ми не передаємо четвертий аргумент у pwrite. Так, для розріджених файлів:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Написання одного байта зі зміщенням ~ 128TiB призвело до xfs, використовуючи простір 300кіБ для зберігання карти масштабу, я думаю. Не спробуйте це в OS X з HFS +: IIRC, HFS + не підтримує розріджені файли, тому він заповнить диск.
XFS - це правильна 64-бітна файлова система, що підтримує окремі файли до 8 екбабайтів . тобто 2 ^ 63-1, максимальне значення off_tможе містити.
strace вихід:
open("a", O_WRONLY|O_CREAT, 03777711166007270) = 3
pwrite(3, "\0", 1, 139989929353760) = 1
sync() = 0
pwrite(3, "\0", 1, 139989929380071) = 1
sync() = 0
...
/dev/null? (Чиyes>/dev/nullдійсна відповідь Баша?)