C amd64 Linux पर, 36 बाइट्स (केवल टाइमस्टैम्प), 52 49 बाइट्स (वास्तविक डिस्क गतिविधि)
मैं open(2)
झंडे को हार्ड-कोड करता हूं , इसलिए यह अन्य एबीआई के लिए पोर्टेबल नहीं है। अन्य प्लेटफार्मों पर लिनक्स संभवतः उसी का उपयोग करता है O_TRUNC
, आदि, लेकिन अन्य POSIX OSes नहीं हो सकता है।
+4 बाइट्स यह सुनिश्चित करने के लिए एक सही अनुमति प्राप्त करने के लिए कि फाइल मालिक के उपयोग के साथ बनाई गई है, नीचे देखें। (यह 5.2 gcc के साथ काम करने के लिए होता है)
कुछ हद तक पोर्टेबल ANSI C, 38/51 बाइट्स (केवल टाइमस्टैम्प), 52/67 बाइट्स (वास्तविक डिस्क गतिविधि)
@ बिल्ली के जवाब के आधार पर, @ जेन्स से एक टिप के साथ।
पहले नंबर कार्यान्वयन जहां एक के लिए है int
पकड़ कर सकते हैं FILE *fopen()
अगर हम ऐसा नहीं कर सकते की वापसी मान, दूसरा नंबर। लिनक्स पर, ढेर पते कम स्थान के पते के 32 बिट्स में होते हैं, इसलिए यह बिना -m32
या के भी काम करता है -mx32
। (घोषणा void*fopen();
से कम है #include <stdio.h>
)
टाइमस्टैम्प मेटाडेटा I / O केवल :
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"));}
एक बाइट लिख रहा है, वास्तव में लिनक्स पर डिस्क मार रहा है 4.2.0 + XFS + lazytime
:
main(){for(;write(open("a",577),"",1);close(3));}
write
फॉर-लूप की स्थिति है, जो ठीक है क्योंकि यह हमेशा रिटर्न करता है 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
गैर-पोर्टेबल संस्करण की व्याख्या:
फ़ाइल यादृच्छिक कचरा अनुमतियों के साथ बनाई गई है। साथ gcc
5.2, के साथ -O0
या -O3
, यह मालिक लिखने की अनुमति शामिल करने के लिए होता है, लेकिन यह गारंटी नहीं है। 0666
दशमलव 438 है। एक तीसरा arg open
एक और 4 बाइट्स लेगा । हम पहले से ही O_TRUNC और इतने पर हार्ड-कोडिंग कर रहे हैं, लेकिन यह एक ही एबीआई पर एक अलग संकलक या libc के साथ टूट सकता है।
हम 2 वें arg को छोड़ नहीं सकते हैं open
, क्योंकि कचरा मान शामिल करने के लिए होता है O_EXCL
, और O_TRUNC|O_APPEND
, इसलिए खुला विफल रहता है EINVAL
।
हमें वापसी मूल्य को बचाने की आवश्यकता नहीं है open()
। हम इसे मान लेते हैं 3
, क्योंकि यह हमेशा रहेगा। यहां तक कि अगर हम fd 3 के साथ शुरू करते हैं, तो यह पहले पुनरावृत्ति के बाद बंद हो जाएगा। सबसे खराब स्थिति, open
3 के अंतिम उपलब्ध फ़ाइल डिस्क्रिप्टर तक नए एफडी खोलते रहते हैं। तो, पहले 65531 write()
कॉल के साथ विफल हो सकता है EBADF
, लेकिन फिर हर open
बनाने के साथ सामान्य रूप से काम करेंगे fd = 3।
577 = 0x241 = O_WRONLY|O_CREAT|O_TRUNC
x86-64 लिनक्स पर। बिना O_TRUNC
, इनकोड मॉड समय और परिवर्तन समय अपडेट नहीं किया जाता है, इसलिए एक छोटा arg संभव नहीं है। O_TRUNC
उस संस्करण के लिए अभी भी आवश्यक है जो write
वास्तविक डिस्क गतिविधि का उत्पादन करने के लिए कहता है, न कि फिर से लिखना।
मुझे कुछ उत्तर मिलते हैं open("a",1)
। यदि a
पहले से मौजूद नहीं है, तो O_CREAT आवश्यक है। O_CREAT
लिनक्स पर ऑक्टल 0100 (64, 0x40) के रूप में परिभाषित किया गया है।
कोई संसाधन लीक नहीं होता है, इसलिए यह हमेशा के लिए चल सकता है। 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
मुझे अपने C ++ वर्जन पर open
उपयोग करके इस ABI के झंडे का दशमलव मान मिला strace -eraw=open
।
लिनक्स lazytime
माउंट विकल्प सक्षम के साथ एक फाइलसिस्टम पर , केवल इनोड टाइमस्टैम्प को प्रभावित करने वाला परिवर्तन केवल 24 घंटे में एक लिखने का कारण होगा। उस माउंट विकल्प के साथ अक्षम, टाइमस्टैम्प अद्यतन आपके SSD को पहनने के लिए एक व्यवहार्य तरीका हो सकता है। (हालांकि, कई अन्य उत्तर केवल मेटाडेटा I / O करते हैं)।
विकल्प:
कम गैर-काम :
main(){for(;;)close(write(open("a",577),"",3));}
write
पास करने के लिए एक 3
arg पास करने के लिए रिटर्न वैल्यू का उपयोग करता है । यह एक और बाइट बचाता है, लेकिन amd64 पर gcc -O0 या -O3 के साथ काम नहीं करता है। 3rd arg में कचरा open
अलग है, और इसमें लिखित अनुमति शामिल नहीं है। a
पहली बार बनाया जाता है, लेकिन भविष्य के पुनरावृत्तियों के साथ सभी विफल हो जाते हैं -EACCESS
।
अब, विभिन्न सिस्टम कॉल के साथ काम करना :
main(c){for(open("a",65);pwrite(3,"",1);)sync();}
एक बाइट में जगह फिर से लिखता है और sync()
सभी फाइल सिस्टम-सिस्टम को सिंक करने के लिए कहता है। इससे ड्राइव की लाइट जलती रहती है।
हमें परवाह नहीं है कि कौन सा बाइट है, इसलिए हम 4 वें arg को pwrite पास नहीं करते हैं। विरल फ़ाइलों के लिए याय:
$ ll -s a
300K -rwx-wx--- 1 peter peter 128T May 15 11:43 a
~ 128TiB की भरपाई में एक बाइट लिखने से 300kB स्पेस का उपयोग करते हुए एक्सफ़ के लिए हद का नक्शा पकड़ लिया, मुझे लगता है। HFS +: IIRC, HFS + के साथ OS X पर यह कोशिश न करें, यह विरल फाइलों का समर्थन नहीं करता है, इसलिए यह डिस्क को भर देगा।
एक्सएफएस एक उचित 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
एक वैध बैश जवाब?)