C pada amd64 Linux, 36 byte (hanya timestamp), 52 49 byte (aktivitas disk nyata)
Saya membuat kode yang sulit pada open(2)
flag, jadi ini tidak portabel untuk ABI lain. Linux pada platform lain kemungkinan menggunakan hal yang sama O_TRUNC
, dll., Tetapi OS POSIX lain mungkin tidak.
+4 byte untuk memberikan arg izin yang benar untuk memastikan file dibuat dengan akses tulis pemilik, lihat di bawah. (Ini terjadi untuk bekerja dengan gcc 5.2)
ANSI C agak portabel, 38/51 byte (hanya cap waktu), 52/67 byte (aktivitas disk nyata)
Berdasarkan jawaban @ Cat, dengan tip dari @Jens.
Angka pertama adalah untuk implementasi di mana suatu int
dapat menyimpan FILE *fopen()
nilai kembali, nomor kedua jika kita tidak bisa melakukan itu. Di Linux, tumpukan alamat kebetulan berada di ruang alamat 32 bit yang rendah, sehingga bisa berfungsi bahkan tanpa -m32
atau -mx32
. (Mendeklarasikan void*fopen();
lebih pendek dari #include <stdio.h>
)
Hanya metadata I / O stempel waktu :
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"));}
Menulis byte, sebenarnya memukul disk di Linux 4.2.0 + XFS + lazytime
:
main(){for(;write(open("a",577),"",1);close(3));}
write
adalah kondisi for-loop, yang baik-baik saja karena selalu mengembalikan 1. close
adalah kenaikan.
// 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
Penjelasan dari versi non-portabel:
File dibuat dengan izin sampah acak. Dengan gcc
5.2, dengan -O0
atau -O3
, itu terjadi untuk menyertakan izin menulis pemilik, tetapi ini tidak dijamin. 0666
adalah desimal 438. Arg ke-3 open
akan membutuhkan 4 byte lagi . Kami sudah mengkodekan O_TRUNC dan seterusnya, tetapi ini bisa terputus dengan kompiler atau libc yang berbeda pada ABI yang sama.
Kita tidak dapat menghilangkan argumen ke-2 open
, karena nilai sampah kebetulan termasuk O_EXCL
, dan O_TRUNC|O_APPEND
, jadi gagal gagal EINVAL
.
Kami tidak perlu menyimpan nilai pengembalian dari open()
. Kami berasumsi itu 3
, karena akan selalu begitu. Bahkan jika kita mulai dengan fd 3 terbuka, itu akan ditutup setelah iterasi pertama. Kasing terburuk, open
terus membuka fds baru hingga 3 adalah deskriptor file terakhir yang tersedia. Jadi, hingga 65531 write()
panggilan pertama bisa gagal EBADF
, tetapi kemudian akan bekerja secara normal dengan setiap open
pembuatan fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNC
di x86-64 Linux. Tanpa O_TRUNC
, waktu mod inode dan waktu perubahan tidak diperbarui, jadi arg yang lebih pendek tidak mungkin. O_TRUNC
masih penting untuk versi yang memanggil write
untuk menghasilkan aktivitas disk yang sebenarnya, bukan menulis ulang di tempat.
Saya melihat beberapa jawaban itu open("a",1)
. O_CREAT diperlukan jika a
belum ada. O_CREAT
didefinisikan sebagai oktal 0100 (64, 0x40) di Linux.
Tidak ada sumber daya bocor, sehingga bisa berjalan selamanya. strace
keluaran:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
atau
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
Saya mendapat nilai desimal dari open
flag untuk ABI ini menggunakan strace -eraw=open
versi C ++ saya.
Pada sistem file dengan lazytime
opsi pemasangan Linux diaktifkan, perubahan yang hanya memengaruhi cap waktu inode hanya akan menyebabkan satu penulisan per 24 jam. Dengan opsi pemasangan yang dinonaktifkan, pemutakhiran stempel waktu mungkin merupakan cara yang layak untuk memakai SSD Anda. (Namun, beberapa jawaban lain hanya melakukan metadata I / O).
alternatif:
lebih pendek tidak bekerja :
main(){for(;;)close(write(open("a",577),"",3));}
menggunakan write
nilai balik untuk melewatkan 3
arg untuk menutup. Ini menyimpan byte lain, tetapi tidak bekerja dengan gcc -O0 atau -O3 pada amd64. Sampah di arg ke-3 open
berbeda, dan tidak termasuk izin menulis. a
akan dibuat pertama kali, tetapi iterasi di masa mendatang semuanya gagal -EACCESS
.
lebih lama, bekerja, dengan panggilan sistem yang berbeda :
main(c){for(open("a",65);pwrite(3,"",1);)sync();}
menulis ulang byte di tempat dan panggilan sync()
untuk menyinkronkan semua sistem file di seluruh sistem. Ini membuat lampu drive menyala.
Kami tidak peduli byte mana, jadi kami tidak meneruskan argumen ke 4 ke pwrite. Yay untuk file jarang:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Menulis satu byte pada offset ~ 128TiB menyebabkan xfs menggunakan 300kiB ruang untuk menampung peta sebatas, saya kira. Jangan coba ini di OS X dengan HFS +: IIRC, HFS + tidak mendukung file jarang, sehingga akan mengisi disk.
XFS adalah sistem file 64bit yang tepat, mendukung masing-masing file hingga 8 exabytes . yaitu 2 ^ 63-1, nilai maksimum off_t
dapat disimpan.
strace
keluaran:
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
? (Apakahyes>/dev/null
jawaban Bash yang valid?)