आप स्मृति पदचिह्न को कम करने की जरूरत है, तो आप Get-ChildItem
का उपयोग कर दें और इसके बजाय सीधे एक .NET एपीआई का उपयोग करें। मैं यह सोचते करती हूं कि आप PowerShell V2 पर कर रहे हैं, यदि ऐसा है तो पहले PowerShell V2 में लोड करने के लिए .NET 4 सक्षम करने के चरण here का पालन करें।
.NET 4 में फाइलों और निर्देशिकाओं के लिए कुछ अच्छे एपीआई हैं, जो उन्हें सरणी में लौटने के विपरीत हैं।
[IO.Directory]::EnumerateFiles("C:\logs") |%{ <move file $_> }
इस एपीआई [IO.Directory]::GetFiles()
का उपयोग कर के बजाय करके, केवल एक ही फ़ाइल नाम एक समय में कार्रवाई की जाएगी, तो स्मृति की खपत अपेक्षाकृत छोटे होना चाहिए।
संपादित
मैं भी यह सोचते हैं आप था Get-ChildItem |ForEach { process }
की तरह एक साधारण pipelined दृष्टिकोण की कोशिश की थी। यदि यह पर्याप्त है, तो मैं सहमत हूं कि यह जाने का तरीका है।
लेकिन मैं एक आम गलत धारणा स्पष्ट करने के लिए करना चाहते हैं: वी 2 में, Get-ChildItem
(या वास्तव में, FileSystem प्रदाता) सही मायने में स्ट्रीम नहीं करता है। कार्यान्वयन एपीआई Directory.GetDirectories
और Directory.GetFiles
है, जो अपने मामले में एक 1.6M-तत्व वाली सरणी से पहले किसी भी प्रसंस्करण हो सकता है उत्पन्न होगा उपयोग करता है। एक बार यह हो जाने के बाद, हाँ, पाइपलाइन का शेष स्ट्रीमिंग हो रहा है। और हां, इस शुरुआती निम्न-स्तरीय टुकड़े के अपेक्षाकृत कम प्रभाव पड़ता है, क्योंकि यह केवल एक स्ट्रिंग सरणी है, अमीर FileInfo
ऑब्जेक्ट्स की एक सरणी नहीं है। लेकिन यह दावा करना गलत है कि इस पैटर्न में O(1)
मेमोरी का उपयोग किया जाता है।
इसके विपरीत, पावरहेल v3, .NET 4 पर बनाया गया है, और इस प्रकार ऊपर उल्लिखित स्ट्रीमिंग एपीआई का लाभ उठाता है (Directory.EnumerateDirectories
और Directory.EnumerateFiles
)। यह एक अच्छा बदलाव है, और परिदृश्य में आपकी तरह ही मदद करता है।
अच्छा और सरल समाधान के लिए धन्यवाद। मैंने हमेशा सोचा था कि शक्तियों में पाइपलाइनिंग अगले कार्य को संसाधित करने से पहले पूरे परिणाम को वापस कर देगी। –
यह वास्तव में अभी भी 'ओ (एन)' स्मृति की आवश्यकता है, लेकिन यदि यह समस्या हल करता है तो मैं मानता हूं कि यह सबसे अच्छा समाधान है। – latkin