दिलचस्प पोस्ट
आप जावा में ऑब्जेक्ट की एक गहरी कॉपी कैसे बनाते हैं? जीएसएएन ने "अपेक्षित BEGIN_OBJECT फेंक रहा था लेकिन BEGIN_ARRAY था"? अजगर में एक स्ट्रिंग में एस्केप एजेक्शन प्रक्रिया करें ':' (कोलन) जावास्क्रिप्ट में क्या करता है? कोर डेटा बनाम SQLite 3 यह निर्धारित करने के लिए कि क्या कोई बिंदु 2 डी त्रिकोण में है? वेरिएबल के नाम से पहले स्टाइल, बजाय टाइप के बाद क्यों? जावास्क्रिप्ट का उपयोग करते हुए पीडीएफ HTML से div में उत्पन्न करें नक्शे के सी + + नक्शे के माध्यम से कैसे लूप करें? सूची से एक मूल्य के सभी घटनाओं को निकालें? क्या मुझे गुणन या विभाजन का उपयोग करना चाहिए? PHP कर्ल और कुकीज़ अनुरोधों के साथ अजगर में बड़ी फाइल कैसे डाउनलोड करें? कैसे प्रोग्रामिंग आईफोन पर एसएमएस भेजें? जावा सूची.contains (x के बराबर फ़ील्ड मान के साथ ऑब्जेक्ट)

लिनक्स पर एक खुली फाइल हैंन्डलर का क्या होता है, यदि पॉइंट फाइल को स्थानांतरित किया जाता है, हटाएं

लिनक्स पर एक खुली फाइल हैंन्डलर का क्या होता है, अगर उस वक्त पॉइंट फाइल हो तो:

  • दूर ले जाया गया -> क्या फ़ाइल हैंडलर वैध रहता है?
  • हटाए गए -> क्या यह एक ईबीएडीएफ की ओर ले जाता है, जो कि एक अमान्य फ़ाइल हैंडलर का संकेत देता है?
  • एक नई फ़ाइल से बदलकर -> क्या फ़ाइल हैंडलर इस नई फ़ाइल की ओर इशारा करता है?
  • एक नई फ़ाइल के लिए हार्ड लिंक से बदलें -> क्या मेरी फ़ाइल हैंडलर इस लिंक का "अनुसरण करें" है?
  • एक नरम लिंक से एक नई फ़ाइल में बदलें -> क्या मेरी फ़ाइल हैंडलर अब इस नरम लिंक फ़ाइल को प्रभावित करती है?

मैं ऐसे प्रश्न क्यों पूछ रहा हूं: मैं हॉट-प्लग किए गए हार्डवेयर (जैसे USB डिवाइस आदि) का उपयोग कर रहा हूं। ऐसा हो सकता है, कि डिवाइस (और यह / dev / file भी) उपयोगकर्ता या किसी अन्य Gremlin द्वारा रिटाकेट हो जाता है।

इस से संबंधित सर्वोत्तम अभ्यास क्या है?

वेब के समाधान से एकत्रित समाधान "लिनक्स पर एक खुली फाइल हैंन्डलर का क्या होता है, यदि पॉइंट फाइल को स्थानांतरित किया जाता है, हटाएं"

यदि फ़ाइल को उसी फाइल सिस्टम में ले जाया गया है या उसका नाम बदल दिया गया है, तो फ़ाइल संभाल खुला रहता है और अभी भी फ़ाइल पढ़ने और लिखने के लिए उपयोग किया जा सकता है।

अगर फ़ाइल हटाई जाती है, तो फ़ाइल संभाल खुला रहता है और इसका उपयोग अभी भी किया जा सकता है (यह कुछ लोगों की अपेक्षा नहीं है)। अंतिम संभाल बंद होने तक फ़ाइल वास्तव में नहीं हटाई जाएगी।

यदि फाइल को एक नई फ़ाइल से बदल दिया गया है, तो यह बिल्कुल कैसे निर्भर करता है अगर फ़ाइल की सामग्री को ओवरराइट किया गया है, तो फ़ाइल संभाल अभी भी मान्य होगी और नई सामग्री तक पहुंच जाएगी। अगर मौजूदा फ़ाइल अनलिंक हो गई है और एक ही नाम के साथ एक नया बनाया गया है या, यदि कोई नया फाइल rename() के द्वारा मौजूदा फाइल पर स्थानांतरित हो गई है, तो यह विलोपन के समान है (ऊपर देखें) – अर्थात फ़ाइल संभाल जारी रहेगा फ़ाइल के मूल संस्करण को संदर्भित करने के लिए

सामान्य तौर पर, फाइल खोलने के बाद, फ़ाइल खुली हो जाती है, और कोई भी निर्देशिका संरचना बदल नहीं सकता जिसे वह बदल सकता है – वे फ़ाइल का नाम बदल सकते हैं, नाम बदल सकते हैं, या कुछ और जगह रख सकते हैं, यह केवल खुला रहता है

यूनिक्स में कोई डिलीट नहीं है, केवल unlink() , जो समझ में आता है क्योंकि यह जरूरी नहीं कि फ़ाइल को हटाएगा – बस निर्देशिका से लिंक को निकाल देगा


यदि दूसरी तरफ अंतर्निहित डिवाइस गायब हो जाती है (जैसे यूएसबी अनप्लग) तो फ़ाइल संभाल किसी भी अधिक मान्य नहीं होगा और आईओ / त्रुटि किसी भी ऑपरेशन पर दे सकता है। आपको अभी भी इसे बंद करना है यह सच हो रहा है, भले ही डिवाइस को वापस प्लग कर दिया गया हो, क्योंकि इस मामले में फ़ाइल खोलने के लिए समझदार नहीं है।

फ़ाइल किसी इनोड को किसी पथ के बिना इंगित करता है, इसलिए आपके अधिकांश परिदृश्य अभी भी काम करते हैं जैसे आप मानते हैं, क्योंकि संभाल अभी भी फाइल को इंगित करता है।

विशेष रूप से, हटाए गए परिदृश्य के साथ- फ़ंक्शन को किसी कारण के लिए "अनलिंक" कहा जाता है, यह फ़ाइल नाम (एक दंत) और एक फ़ाइल के बीच एक "लिंक" को नष्ट करता है जब आप कोई फ़ाइल खोलते हैं, तो इसे अनलिंक करें, फ़ाइल वास्तव में अभी भी मौजूद है जब तक कि इसकी संदर्भ संख्या शून्य तक नहीं जाती, जो कि जब आप हैंडल बंद करते हैं

संपादित करें: हार्डवेयर के मामले में, आपने एक विशिष्ट डिवाइस नोड के लिए एक हैंड खोल दिया है, यदि आप डिवाइस को अनप्लग कर लेते हैं, तो कर्नेल इसकी सभी पहुंच विफल कर देगा, भले ही डिवाइस वापस आ जाए। आपको डिवाइस को बंद करना होगा और इसे फिर से खोलना होगा।

मुझे अन्य परिचालनों के बारे में निश्चित नहीं है, लेकिन विलोपन के लिए: फ़ाइल को अंतिम ओपन हैंडल बंद होने तक तक विलोपन केवल (फ़ाइल सिस्टम में) शारीरिक रूप से नहीं होता है। इस प्रकार यह एक फ़ाइल को अपने आवेदन के नीचे से हटाना संभव नहीं होना चाहिए।

कुछ एप्लिकेशन (जो दिमाग में नहीं आते हैं) इस व्यवहार पर भरोसा करते हैं, फ़ाइलों को बनाते, खोलते और तुरंत हटाते हैं, जो तब तक वास्तव में लंबे समय तक रहते हैं – अन्य अनुप्रयोगों को बिना किसी आवश्यकता के पहले एप के जीवनचक्र के बारे में जानकारी देने की अनुमति देता है प्रक्रिया नक्शे और इस तरह देखो

ऐसा संभव है कि अन्य सामानों पर समान विचार लागू होते हैं।

यदि आप यह देखना चाहते हैं कि फाइल हैंडलर (फ़ाइल डिस्क्रिप्टर) ठीक है, तो आप इस फ़ंक्शन को कॉल कर सकते हैं।

 /** * version : 1.1 * date : 2015-02-05 * func : check if the fileDescriptor is fine. */ #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> /** * On success, zero is returned. On error, -1 is returned, and errno is set * appropriately. */ int check_fd_fine(int fd) { struct stat _stat; int ret = -1; if(!fcntl(fd, F_GETFL)) { if(!fstat(fd, &_stat)) { if(_stat.st_nlink >= 1) ret = 0; else printf("File was deleted!\n"); } } if(errno != 0) perror("check_fd_fine"); return ret; } int main() { int fd = -1; fd = open("/dev/ttyUSB1", O_RDONLY); if(fd < 0) { perror("open file fail"); return -1; } // close or remove file(remove usb device) // close(fd); sleep(5); if(!check_fd_fine(fd)) { printf("fd okay!\n"); } else { printf("fd bad!\n"); } close(fd); return 0; } 

हटाई गई फ़ाइल की इन-मेमरी जानकारी (आपके द्वारा दी गई सभी उदाहरियां हटाई हुई फ़ाइल के उदाहरण हैं) साथ ही साथ इनोड ऑन-डिस्क अस्तित्व में रहती हैं जब तक फ़ाइल बंद नहीं होती है।

हॉटप्लग किए गए हार्डवेयर पूरी तरह से एक अलग मुद्दा है, और आपको अपने कार्यक्रम को लंबे समय तक जीवित रहने की उम्मीद नहीं करनी चाहिए अगर ऑन-डिस्क इनोड्स या मेटाडेटा बिल्कुल बदल गया हो

/ Proc / निर्देशिका के अंतर्गत आपको वर्तमान में सक्रिय सभी प्रक्रियाओं की एक सूची मिल जाएगी, बस अपने पीआईडी ​​को ढूंढें और संबंधित सभी डेटा वहां मौजूद है। एक अंतरफलक जानकारी फ़ोल्डर है fd /, आप वर्तमान में प्रक्रिया द्वारा खोले गए सभी फाइल हैंडलर्स पाएंगे।

अंत में आप अपने डिवाइस (यदि / dev / या even / proc / bus / usb /) के तहत एक सांकेतिक लिंक मिल जाएंगे, यदि डिवाइस लटका हुआ है तो वह मृत हो जाएगा और इस हैंडल को ताज़ा करना असंभव होगा, प्रक्रिया बंद होनी चाहिए और इसे फिर से खोलें (रीकनेक्शन के साथ भी)

यह कोड आपके पीआईडी ​​लिंक की वर्तमान स्थिति को पढ़ सकता है

 #include <unistd.h> #include <stdio.h> #include <dirent.h> int main() { // the directory we are going to open DIR *d; // max length of strings int maxpathlength=256; // the buffer for the full path char path[maxpathlength]; // /proc/PID/fs contains the list of the open file descriptors among the respective filenames sprintf(path,"/proc/%i/fd/",getpid() ); printf("List of %s:\n",path); struct dirent *dir; d = opendir(path); if (d) { //loop for each file inside d while ((dir = readdir(d)) != NULL) { //let's check if it is a symbolic link if (dir->d_type == DT_LNK) { const int maxlength = 256; //string returned by readlink() char hardfile[maxlength]; //string length returned by readlink() int len; //tempath will contain the current filename among the fullpath char tempath[maxlength]; sprintf(tempath,"%s%s",path,dir->d_name); if ((len=readlink(tempath,hardfile,maxlength-1))!=-1) { hardfile[len]='\0'; printf("%s -> %s\n", dir->d_name,hardfile); } else printf("error when executing readlink() on %s\n",tempath); } } closedir(d); } return 0; } 

यह अंतिम कोड सरल है, आप लिंकैट फ़ंक्शन के साथ खेल सकते हैं।

 int open_dir(char * path) { int fd; path = strdup(path); *strrchr(path, '/') = '\0'; fd = open(path, O_RDONLY | O_DIRECTORY); free(path); return fd; } int main(int argc, char * argv[]) { int odir, ndir; char * ofile, * nfile; int status; if (argc != 3) return 1; odir = open_dir(argv[1]); ofile = strrchr(argv[1], '/') + 1; ndir = open_dir(argv[2]); nfile = strrchr(argv[2], '/') + 1; status = linkat(odir, ofile, ndir, nfile, AT_SYMLINK_FOLLOW); if (status) { perror("linkat failed"); } return 0; }