C unter amd64 Linux, 36 Bytes (nur Zeitstempel), 52 49 Bytes (echte Festplattenaktivität)
Ich codiere die open(2)Flags hart , so dass dies nicht auf andere ABIs übertragbar ist. Linux auf anderen Plattformen verwendet wahrscheinlich dasselbe O_TRUNCusw., andere POSIX-Betriebssysteme jedoch möglicherweise nicht.
+4 Bytes , um ein korrektes Berechtigungsargument zu übergeben, um sicherzustellen, dass die Datei mit dem Schreibzugriff des Besitzers erstellt wurde (siehe unten). (Dies funktioniert mit gcc 5.2)
etwas portables ANSI C, 38/51 Bytes (nur Zeitstempel), 52/67 Bytes (echte Festplattenaktivität)
Basierend auf der Antwort von @ Cat, mit einem Tipp von @Jens.
Die erste Zahl ist für Implementierungen intgedacht FILE *fopen(), bei denen der Rückgabewert eines can hold ist, die zweite Zahl, wenn wir das nicht können. Unter Linux befinden sich Heap-Adressen in den unteren 32 Bit des Adressraums, daher funktioniert dies auch ohne -m32oder -mx32. (Deklaration void*fopen();ist kürzer als #include <stdio.h>)
Nur Zeitstempel-Metadaten-E / A :
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"));}
Schreiben eines Bytes unter Linux 4.2.0 + XFS + lazytime:
main(){for(;write(open("a",577),"",1);close(3));}
writeist die for-Schleifenbedingung, die in Ordnung ist, da sie immer 1 zurückgibt. Ist closedas Inkrement.
// 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
Erklärung der nicht portierbaren Version:
Die Datei wird mit zufälligen Speicherbereinigungen erstellt. In gccVersion 5.2, mit -O0oder -O3, ist möglicherweise eine Schreibberechtigung für den Eigentümer enthalten, dies kann jedoch nicht garantiert werden. 0666ist dezimal 438. Ein drittes Argument für openwürde weitere 4 Bytes benötigen . Wir haben bereits O_TRUNC und so weiter hartcodiert, aber dies kann mit einem anderen Compiler oder einer anderen libc auf demselben ABI zu Problemen führen.
Wir können nicht die 2. arg verzichten open, da der Garbage Wert enthalten geschieht O_EXCL, und O_TRUNC|O_APPEND, so offen nicht mit EINVAL.
Der Rückgabewert von muss nicht gespeichert werden open(). Wir gehen davon aus 3, dass es so ist , weil es immer so sein wird. Auch wenn wir mit fd 3 open beginnen, wird es nach der ersten Iteration geschlossen. Im schlimmsten Fall werden so lange openneue FDS geöffnet, bis 3 der letzte verfügbare Dateideskriptor ist. Bis zu den ersten 65531- write()Aufrufen konnte dies fehlschlagen EBADF, funktioniert dann aber normal mit jeder openErstellung von fd = 3.
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNCunter x86-64 Linux. Ohne O_TRUNCwerden die Inode-Mod-Zeit und die Änderungszeit nicht aktualisiert, so dass ein kürzeres Argument nicht möglich ist. O_TRUNCist immer noch wichtig für die Version, die writezum Erzeugen der tatsächlichen Festplattenaktivität aufruft , und nicht zum erneuten Schreiben.
Ich sehe einige Antworten darauf open("a",1). O_CREAT ist erforderlich, falls anoch nicht vorhanden. O_CREATist unter Linux als oktal 0100 (64, 0x40) definiert.
Keine Ressourcenlecks, daher kann es für immer ausgeführt werden. straceAusgabe:
open("a", O_WRONLY|O_CREAT|O_TRUNC, 03777762713526650) = 3
close(3) = 0
... repeating
oder
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
Ich habe den Dezimalwert der openFlags für dieses ABI strace -eraw=openin meiner C ++ - Version erhalten.
Auf einem Dateisystem mit lazytimeaktivierter Linux- Mount-Option führt eine Änderung, die sich nur auf Inode-Zeitstempel auswirkt, nur zu einem Schreibvorgang pro 24 Stunden. Wenn diese Einhängeoption deaktiviert ist, kann die Zeitstempelaktualisierung möglicherweise die SSD strapazieren. (Einige andere Antworten führen jedoch nur Metadaten-E / A aus.)
Alternativen:
kürzer arbeitslos :
main(){for(;;)close(write(open("a",577),"",3));}Verwendet writeden Rückgabewert von 's, um ein 3Argument zum Schließen zu übergeben. Es speichert ein weiteres Byte, funktioniert aber nicht mit gcc -O0 oder -O3 auf amd64. Der Müll im 3. Argument openist anders und enthält keine Schreibrechte. awird das erste Mal erstellt, aber zukünftige Iterationen scheitern alle mit -EACCESS.
länger arbeiten, mit verschiedenen Systemaufrufen :
main(c){for(open("a",65);pwrite(3,"",1);)sync();} Schreibt ein Byte an Ort und Stelle neu und ruft sync()auf, um alle Dateisysteme systemweit zu synchronisieren. Dadurch bleibt die Laufwerksanzeige eingeschaltet.
Es ist uns egal welches Byte, also übergeben wir das 4. Argument nicht an pwrite. Ja für spärliche Dateien:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
Das Schreiben eines Bytes mit einem Offset von ~ 128 TB führte dazu, dass xfs 300 KB Speicherplatz für die Extent-Map benötigte. Versuchen Sie dies nicht unter OS X mit HFS +: IIRC, HFS + unterstützt keine Sparse-Dateien, daher wird die Festplatte gefüllt.
XFS ist ein richtiges 64-Bit-Dateisystem, das einzelne Dateien mit bis zu 8 Exabyte unterstützt . Dh 2 ^ 63-1, der Maximalwert off_tkann halten.
strace Ausgabe:
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? (Istyes>/dev/nulleine gültige Bash-Antwort?)