यूनिक्स फ़ाइल नाम एन्कोडिंग को समझना


25

मुझे यह समझने में कठिन समय है कि फ़ाइल नाम एन्कोडिंग कैसे काम करती है। यूनिक्स पर। मुझे स्पष्टीकरण के विरोधाभासी लगता है।

फ़ाइल नाम वर्णों के रूप में संग्रहीत किए जाते हैं

एक अन्य उत्तर को उद्धृत करने के लिए: लिनक्स पर फ़ाइल-सिस्टम वर्ण एन्कोडिंग के बारे में कई प्रश्न

[…] जैसा कि आप अपने प्रश्न में उल्लेख करते हैं, एक UNIX फ़ाइल नाम केवल वर्णों का एक क्रम है; कर्नेल एन्कोडिंग के बारे में कुछ नहीं जानता है, जो पूरी तरह से एक उपयोगकर्ता-स्थान (यानी, एप्लिकेशन-स्तर) अवधारणा है।

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

निम्नलिखित मान लें: एक उपयोगकर्ता एक यादृच्छिक एन्कोडिंग एक्स का उपयोग करता है , जो फ़ाइल fooको बाइट अनुक्रम α में अनुवाद करता है और इसे डिस्क पर सहेजता है। एक अन्य उपयोगकर्ता एन्कोडिंग वाई का उपयोग करता है । इस एन्कोडिंग में α अनुवाद करता है /, जिसे फ़ाइल नाम के रूप में अनुमति नहीं है। हालाँकि, पहले उपयोगकर्ता के लिए फ़ाइल मान्य है।

मुझे लगता है कि यह परिदृश्य नहीं हो सकता है।

फ़ाइल नाम बाइनरी ब्लॉब्स के रूप में संग्रहीत हैं

एक अन्य उत्तर को उद्धृत करने के लिए: लिनक्स पर फ़ाइल नाम और रास्तों के लिए कौन सी चारसेट एन्कोडिंग का उपयोग किया जाता है?

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

यदि सिस्टम वर्णों के साथ व्यवहार नहीं करता है, तो फ़ाइल नामों में विशेष वर्ण (जैसे /या NULL) कैसे मना किए जा सकते हैं? / एन्कोडिंग के बिना कोई धारणा नहीं है ।

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

मैं यह भी मानता हूं कि यह गलत है।

एन्कोडिंग कहाँ होती है और विशेष पात्रों को अनुमति नहीं देने पर प्रतिबंध कहाँ लगाया जाता है?


सभी एन्कोडिंग्स में नल समान (0) है।
केविन

2
@ केविन काफी नहीं: कहते हैं, यूटीएफ -16, या यूसीएस -4 (= यूटीएफ -32), या अधिकांश अन्य मल्टीबाइट एन्कोडिंग जो एएससीआईआई के विस्तार नहीं हैं।
गाइल्स का SO- बुराई पर रोक '22

1
दरअसल, रिकार्डो मुर्री के जवाब में बाइट्स का उल्लेख होना चाहिए था न कि वहां के पात्रों का । अधिकांश फाइलसिस्टम बाइट्स की दुकान करते हैं।
गाइल्स का SO- बुराई पर रोक '22

@ गिल्स: अभी तक एक और बार you आप वास्तव में क्या लिखा है देखने के लिए देखते हैं ।
इंनिस मिसी

जवाबों:


25

संक्षिप्त उत्तर: यूनिक्स / लिनक्स / बीएसडी कर्नेल, namei()फ़ंक्शन में लगाए गए प्रतिबंध । एन्कोडिंग उपयोगकर्ता स्तर के कार्यक्रमों में होता है जैसे xterm, firefoxया ls

मुझे लगता है कि आप गलत परिसर से शुरू कर रहे हैं। यूनिक्स में एक फ़ाइल नाम मनमाने ढंग से मूल्यों के साथ बाइट्स का एक स्ट्रिंग है। कुछ मान, 0x0 (ASCII Nul) और 0x2f (ASCII '/') को अनुमति नहीं है, मल्टी-बाइट कैरेक्टर एन्कोडिंग के हिस्से के रूप में नहीं, कुछ भी नहीं के रूप में। एक "बाइट" में एक वर्ण (एएससीआईआई और कुछ अन्य एन्कोडिंग) का प्रतिनिधित्व करने वाली संख्या हो सकती है, लेकिन एक "चरित्र" के लिए 1 बाइट से अधिक की आवश्यकता हो सकती है (उदाहरण के लिए, यूटीएफ -8 के यूएक्सोड के 0x7f से ऊपर कोड बिंदु)।

ये प्रतिबंध फ़ाइल नाम मुद्रण सम्मेलनों और ASCII वर्ण सेट से उत्पन्न होते हैं। मूल यूनिक्स ने ASCII '/' (संख्यात्मक रूप से 0x2f) का उपयोग किया, जो आंशिक रूप से या पूरी तरह से योग्य पथ के अलग-अलग टुकड़ों के लिए बाइट्स को महत्व देता है (जैसे '/ usr / bin / cat' में "usr", "बिन और" बिल्ली ") टुकड़े होते हैं। । मूल यूनिक्स ने तार को समाप्त करने के लिए ASCII Nul का उपयोग किया। उन दो मूल्यों के अलावा, फ़ाइल नामों में बाइट्स किसी भी अन्य मूल्य मान सकते हैं। आप यूनिकोड के लिए UTF-8 एन्कोडिंग में इसकी एक प्रतिध्वनि देख सकते हैं। मुद्रण योग्य ASCII वर्ण, '/' सहित, UTF-8 में केवल एक बाइट लेते हैं। उपर्युक्त कोड बिंदुओं के लिए UTF-8 में शून्य नियंत्रण वर्ण को छोड़कर कोई शून्य-मूल्यवान बाइट्स शामिल नहीं है। यूटीएफ -8 का आविष्कार प्लान -9, द प्रिटेंडर टू द सिंहासन ऑफ यूनिक्स के लिए किया गया था।

पुराने यूनिक्स (और यह लिनक्स की तरह दिखता है) में एक namei()फ़ंक्शन था जो बस एक समय में एक बाइट को देखता है, और 0x2F मूल्यवान बाइट्स पर पथों को टुकड़ों में तोड़ता है, एक शून्य-मूल्यवान बाइट पर रोक देता है। namei()यूनिक्स / लिनक्स / बीएसडी कर्नेल का हिस्सा है, इसलिए जहां असाधारण बाइट मूल्यों को लागू किया जाता है।

ध्यान दें कि अब तक, मैंने बाइट के मूल्यों के बारे में बात की है, पात्रों की नहीं। namei()बाइट्स पर किसी भी वर्ण शब्दार्थ को लागू नहीं करता है। यह उपयोगकर्ता के स्तर के कार्यक्रमों पर निर्भर करता है, जैसे ls, बाइट मान या वर्ण मान के आधार पर फ़ाइल नाम को सॉर्ट कर सकता है। xtermयह तय करता है कि चरित्र एन्कोडिंग के आधार पर फ़ाइल नाम के लिए कौन से पिक्सेल को प्रकाश करना है। यदि आप यह नहीं बताते xtermहैं कि आपको UTF-8 एन्कोडेड फाइलनाम मिल गया है, तो जब आप इसे इनवॉइस करते हैं, तो आप बहुत अधिक अस्पष्ट देखेंगे। यदि आपको vimUTF-8 (या जो भी, UTF-16, UTF-32) एनकोडिंग का पता लगाने के लिए संकलित नहीं किया गया है, तो जब आप UTF-8 एन्कोडेड वर्णों वाली "टेक्स्ट फ़ाइल" खोलते हैं, तो आपको बहुत गालिब दिखाई देंगे।


सही है, namei()1986 के आसपास छोड़ दिया गया था। नए UNIX सिस्टम का उपयोग lookuppn()VFS आधारित है।
विद्वान

17

बात यह है, कर्नेल एक बिट की परवाह नहीं करता है कि कैसे एप्लिकेशन डेटा को एक फ़ाइलनाम के रूप में व्याख्या करता है।

आइए कल्पना करें कि मेरे पास एक सी एप्लिकेशन है जो विशेष रूप से UTF-16 स्ट्रिंग्स से संबंधित है। और मैं एक ठीक से कॉन्फ़िगर इनपुट विधि, Un प्रतीक (यूनिकोड 0x222F) के माध्यम से "Save As" प्रॉम्प्ट / डायलॉग में दर्ज करता हूं।

यदि आवेदन किसी भी प्रकार का अनुवाद नहीं करता है और वह भेजता है, तो एक सादे पुराने सी स्ट्रिंग ( char*) में, कहने के लिए, fopenलिखित मोड में, कर्नेल k नहीं देखेगा, या यहां तक ​​कि कल्पना करने की कोशिश भी नहीं करेगा। यह दो charएस, एक के बाद एक, मूल्यों के साथ 0x22 0x2F(8 लाइब्रेरी में और सी लाइब्रेरी में कोई funnies मान ) देखेंगे ।
यही है, कर्नेल के दृष्टिकोण से, एक वैध चार ( ") के बाद /(ASCII 0x2F)। fopenवापस आएगा EISDIR(यानी "जो एक निर्देशिका की तरह दिखता है और आपने लिखने का अनुरोध किया है!")।
अगर मैंने I (यूनिकोड 0x222E) में प्रवेश किया था , तो कर्नेल ने दो ठीक वर्ण देखे होंगे, और एक फाइल बनाई होगी, जो कि ASCII- बोलने वाले एप्लिकेशन के माध्यम से देखी जाएगी, जिसका नाम होगा ".

अगर मैंने aफ़ाइल नाम के रूप में आवेदन में प्रवेश किया था , और आवेदन ने इसे UTF-16 के साथ कर्नेल में पारित कर दिया, तो कर्नेल पढ़ेगा 0x00 0x61, और वास्तव में इस पर विचार भी नहीं करेगा 0x61, क्योंकि 0x00पहले से ही स्ट्रिंग को समाप्त कर देता है, जहां तक ​​यह है चिंतित। त्रुटि संदेश एक खाली फ़ाइल नाम ( ENOENTमेरा मानना ​​है) के लिए समान होगा ।

तो कर्नेल वास्तव में डेटा को बूँद के रूप में लेता है। यह एस की एक धारा है char। आपकी पसंद के उपयोगकर्ता-स्पेस एन्कोडिंग में अमान्य "वर्ण" वे हैं जो अपने ब्लॉब में उत्पन्न ( 0x00या 0x2F"शून्य" /) और बाइनरी प्रतिनिधित्व जो कर्नेल को पास हो जाते हैं)।


अगर मैं आपको सही कर दूं, तो अमान्य वर्ण जैसी कोई चीज नहीं है। केवल अमान्य बाइट अनुक्रम हैं। और मान 0x00और 0x2Fकर्नेल में हार्ड कोडित हैं। बदले में इसका मतलब है, कि निर्देशिकाओं को अलग नहीं किया जाता है /, लेकिन 0x2Fउपयोग में एन्कोडिंग में जो भी चरित्र नक्शे हैं।
मार्को

हां, यह विचार है यदि आप इसे इस तरह से देखना चाहते हैं। (लेकिन यह गलत हो सकता है। एक कर्नेल में "देशी एन्कोडिंग" /हो सकता है जहां 0x2F नहीं है - charsवास्तव में 8-बिट का उपयोग नहीं कर सकता है।) "पारंपरिक" डायर विभाजक है /। यह 8x बाइट ASCII (उदाहरण के लिए EBCDIC नहीं) सिस्टम पर 0x27 है।
Mat

आप UTF-16BE मान लेते हैं, जबकि UTF-16LE U + 0061 में परिणाम (शून्य-समाप्त) aस्ट्रिंग होगा।
इंनिस मिसी

4

यूनिक्स डिजाइन किए जाने के बाद बाइट्स बनाम वर्णों का पृथक्करण हुआ। जब इसे शब्दों के उपयोग के लिए डिज़ाइन किया गया था तो केवल 8 (या 6, या 9) बिट्स के बारे में कुछ बताया गया था लेकिन शब्द एन्कोडिंग का उल्लेख नहीं किया गया था।

फ़ाइल नाम बाइट्स के अनुक्रम हैं। 0x2f "/" को छोड़कर किसी भी बाइट की अनुमति है। 0x00 युक्त एक बाइट भी स्ट्रिंग टर्मिनेटर के रूप में उपयोग करने के कारण कर्नेल के माध्यम से प्राप्त नहीं कर सकता है। एक अनुप्रयोग बाइट्स के अनुक्रम को एक एन्कोडिंग के अनुसार चुन सकता है। अगर यह गड़बड़ लगता है तो मुझे लगता है कि यह है।

Http://www.gtk.org/api/2.6/glib/glib-Character-Set-Conversion.html पर अधिक जानकारी आपके लिए उपयोगी हो सकती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.