नहीं, किसी फ़ाइल को स्मृति में खोलने पर स्वचालित रूप से पढ़ा नहीं जाता है। यह बहुत ही अयोग्य होगा। sed
, उदाहरण के लिए, लाइन द्वारा इसकी इनपुट लाइन को पढ़ता है, जैसा कि कई अन्य यूनिक्स उपकरण करते हैं। यह शायद ही कभी स्मृति में वर्तमान रेखा से अधिक रखना है।
इसके साथ भी awk
ऐसा ही है। यह एक समय में एक रिकॉर्ड पढ़ता है , जो डिफ़ॉल्ट रूप से एक पंक्ति है। यदि आप इनपुट डेटा के कुछ हिस्सों को चर में स्टोर करते हैं, तो यह अतिरिक्त होगा, निश्चित रूप से 1 ।
कुछ लोगों को जैसे काम करने की आदत होती है
for line in $(cat file); do ...; done
चूंकि शेल को लूप $(cat file)
के पहले पुनरावृत्ति को चलाने से पहले कमांड प्रतिस्थापन का पूरी तरह से विस्तार करना होगाfor
, यह पूरी मेमोरी में पढ़ेगा ( लूप निष्पादित करने वाले शेल द्वारा उपयोग की जाने वाली मेमोरी में )। यह थोड़ा मूर्खतापूर्ण है और अयोग्य भी है। इसके बजाय, एक करना चाहिएfile
for
while IFS= read -r line; do ...; done <file
यह file
लाइन को लाइन से प्रोसेस करेगा (लेकिन "IFS = read -r line" को समझें )।
शेल में लाइन द्वारा फ़ाइलों को संसाधित करना केवल शायद ही कभी आवश्यक होता है, क्योंकि अधिकांश उपयोगिताओं को वैसे भी लाइन-ओरिएंटेड किया जाता है (देखें कि पाठ को खराब अभ्यास के रूप में संसाधित करने के लिए शेल लूप का उपयोग क्यों किया जाता है? )।
मैं जैव सूचना विज्ञान में काम कर रहा हूं, और जब मैं भारी मात्रा में जीनोमिक डेटा का प्रसंस्करण कर रहा हूं, तब तक मैं बहुत कुछ नहीं कर पाऊंगा, जब तक कि मैं केवल डेटा के बिट्स को याद में रखूं। उदाहरण के लिए, जब मुझे वीसीएफ फ़ाइल में डीएनए वेरिएंट वाले 1 टेराबाइट डेटासेट से व्यक्तियों की पहचान करने के लिए उपयोग किए जा सकने वाले डेटा के बिट्स को उतारने की आवश्यकता होती है (क्योंकि उस प्रकार के डेटा को सार्वजनिक नहीं किया जा सकता है), मैं लाइन से लाइन करता हूं एक साधारण awk
कार्यक्रम के साथ प्रसंस्करण (यह संभव है क्योंकि वीसीएफ प्रारूप लाइन-ओरिएंटेड है)। मैं फ़ाइल को मेमोरी में नहीं पढ़ता, इसे वहां प्रोसेस करता हूं , और इसे फिर से लिखता हूं ! यदि फ़ाइल संपीड़ित होती है, तो मैं इसे zcat
या उसके माध्यम से खिलाऊंगा gzip -d -c
, जो gzip
कि डेटा की स्ट्रीम प्रोसेसिंग करता है, पूरी फ़ाइल को मेमोरी में भी नहीं पढ़ेगा।
यहां तक कि फ़ाइल स्वरूपों के साथ जो लाइन ओरिएंटेड नहीं हैं , जैसे कि JSON या XML, स्ट्रीम पार्सर हैं जो रैम में सभी को संग्रहीत किए बिना बड़ी फ़ाइलों को संसाधित करना संभव बनाता है।
निष्पादनयोग्य के साथ, यह थोड़ा अधिक जटिल है क्योंकि साझा पुस्तकालयों को मांग पर लोड किया जा सकता है, और / या प्रक्रियाओं के बीच साझा किया जा सकता है ( उदाहरण के लिए साझा पुस्तकालयों और रैम उपयोग का लोड देखें )।
कैशिंग कुछ ऐसा है जिसका मैंने यहां उल्लेख नहीं किया है। यह डेटा के अक्सर एक्सेस किए गए टुकड़ों को पकड़ने के लिए रैम का उपयोग करने की क्रिया है। ओएस द्वारा छोटी फ़ाइलों (उदाहरण के लिए निष्पादन योग्य) को इस उम्मीद में बंद किया जा सकता है कि उपयोगकर्ता उनके लिए कई संदर्भ बनाएगा। फ़ाइल के पहले पढ़ने के अलावा, बाद में डिस्क के बजाय रैम तक पहुंच बनाई जाएगी। कैशिंग, जैसे इनपुट और आउटपुट की बफरिंग आमतौर पर उपयोगकर्ता के लिए काफी हद तक पारदर्शी होती है और चीजों को कैश करने के लिए उपयोग की जाने वाली मेमोरी की मात्रा गतिशील रूप से अनुप्रयोगों आदि द्वारा आवंटित रैम की मात्रा के आधार पर बदल सकती है।
1 तकनीकी रूप से, अधिकांश प्रोग्राम संभवतया एक समय में इनपुट डेटा का एक हिस्सा पढ़ते हैं, या तो स्पष्ट बफ़रिंग का उपयोग करते हैं, या स्पष्ट रूप से बफरिंग के माध्यम से मानक I / O लाइब्रेरी करते हैं, और फिर उस चंक लाइन को उपयोगकर्ता के कोड से लाइन में प्रस्तुत करते हैं। एक समय में एक चरित्र की तुलना में डिस्क के ब्लॉक आकार के कई को पढ़ना अधिक कुशल है। हालांकि इस चंक का आकार शायद ही मुट्ठी भर किलोबाइट से बड़ा होगा।