2011-11-02 14 views
9

में रिकर्सिव फ़ाइल सूची मैं रुबी (जावा देव होने के लिए) और एक विधि (ओह, माफ करना, एक फ़ंक्शन) को लागू करने की कोशिश कर रहा हूं जो उपनिर्देशिका में सभी फ़ाइलों को पुनः प्राप्त करने और उपज करने के लिए प्रयास करेगी।रुबी

मैं के रूप में यह क्रियान्वित किया है:

def file_list_recurse(dir) 
    Dir.foreach(dir) do |f| 
    next if f == '.' or f == '..' 
    f = dir + '/' + f 
    if File.directory? f 
     file_list_recurse(File.absolute_path f) { |x| yield x } 
    else 
     file = File.new(f) 
     yield file 
    end 
    end 
end 

मेरे प्रश्न हैं:

  1. करता File.new वास्तव में एक फ़ाइल को खोलने? जावा में नई फ़ाइल ("xxx") नहीं है ... अगर मुझे कुछ संरचना उत्पन्न करने की आवश्यकता है जो मैं रूबी में क्या होगा, फ़ाइल फ़ाइल (सीटाइम, आकार इत्यादि) से पूछताछ कर सकता हूं?
  2. {| x | उपज x} मेरे लिए थोड़ा अजीब लग रहा है, क्या यह ठीक है कि इस तरह के पुनरावर्ती कार्यों से उपज है, या इससे बचने का कोई तरीका है?
  3. '।' की जांच करने से बचने का कोई तरीका है और प्रत्येक पुनरावृत्ति पर '..'?
  4. क्या इसे लागू करने का कोई बेहतर तरीका है?

धन्यवाद

पुनश्च: मेरी विधि का नमूना उपयोग कुछ इस तरह है:

curr_file = nil 

file_list_recurse('.') do |file| 
    curr_file = file if curr_file == nil or curr_file.ctime > file.ctime 
end 

puts curr_file.to_path + ' ' + curr_file.ctime.to_s 

(है कि आप पेड़ से सबसे पुरानी फ़ाइल मिलेगा)

= =========

तो, @buruza के लिए धन्यवाद इमोन मैंने महान Dir.glob फ़ंक्शन को पाया जो मुझे कोड की कुछ पंक्तियों को बचाता है। इसके अलावा, @Casper करने के लिए धन्यवाद मैं बाहर File.stat विधि है, जो दो बार File.new

साथ तुलना में तेजी से मेरी समारोह रन बना अंत में पाया मेरे कोड कुछ इस तरह लग रही है:

i=0 
curr_file = nil 

Dir.glob('**/*', File::FNM_DOTMATCH) do |f| 
    file = File.stat(f) 
    next unless file.file? 
    i += 1 
    curr_file = [f, file] if curr_file == nil or curr_file[1].ctime > file.ctime 
end 

puts curr_file[0] + ' ' + curr_file[1].ctime.to_s 
puts "total files #{i}" 

=====

डिफ़ॉल्ट Dir.glob करके फ़ाइल नाम एक बिंदु (* nix में 'छुपा' माना जाता है) के साथ शुरू करने पर ध्यान नहीं देता, तो यह दूसरा तर्क फ़ाइल जोड़ने के लिए बहुत महत्वपूर्ण है :: FNM_DOTMATCH

उत्तर

5

इस बात मुझसे कहता है एक जवाब स्वीकार करने पर विचार करने के लिए, मुझे आशा है कि यह मुझे इसे अपने आप को जवाब दे कोई फ़र्क नहीं पड़ेगा:

i=0 
curr_file = nil 

Dir.glob('**/*', File::FNM_DOTMATCH) do |f| 
    file = File.stat(f) 
    next unless file.file? 
    i += 1 
    curr_file = [f, file] if curr_file == nil or curr_file[1].ctime > file.ctime 
end 

puts curr_file[0] + ' ' + curr_file[1].ctime.to_s 
puts "total files #{i}" 
2

आप अंतर्निहितका उपयोग कर सकते हैंमॉड्यूल की find विधि।

11

इस बारे में कैसे?

puts Dir['**/*.*'] 
+0

कि बहुत अच्छा है!लेकिन यह स्ट्रिंग ऑब्जेक्ट्स का ऐरे उत्पन्न करता है। जो मैं खोज रहा हूं वह वह कार्य है जो फाइल-जैसी संरचना उत्पन्न करेगा ताकि मैं उस पर आधारित अपनी गणना कर सकूं। सबसे बड़ी फाइल ढूँढना, सबसे पुराना सीटा आदि –

+0

Dir ['।'] एक ब्लॉक स्वीकार नहीं करता है। लेकिन Dir.glob करता है! यह प्रश्न # 1 –

5

डॉक्स File.new के अनुसार फ़ाइल को खोलने करता है। आप इसके बजाय File.stat का उपयोग करना चाह सकते हैं, जो फ़ाइल से संबंधित आंकड़ों को एक क्वेरी करने योग्य ऑब्जेक्ट में एकत्रित करता है। लेकिन ध्यान दें कि आंकड़े सृजन के बिंदु पर इकट्ठे होते हैं। जब आप ctime जैसे क्वेरी विधियों को कॉल नहीं करते हैं।

उदाहरण:

Dir['**/*'].select { |f| File.file?(f) }.map { |f| File.stat(f) } 
+1

फ़ाइल को छोड़कर मेरे प्रश्नों का उत्तर देता है। फ़ाइल कानूनी रूप से फाइल का नाम प्रदान नहीं करती है, इसलिए मैं इसे अपनी विधि से वापस करने के लिए डेटा ऑब्जेक्ट के रूप में उपयोग नहीं कर सकता। इसके अलावा, मेरे पास 200,000 फाइलों का पेड़ है। रूबी प्रक्रिया में आपके उदाहरण के परिणाम चलाना 60 एमबी से ऊपर बढ़ता है, जबकि मेरी विधि (फ़ाइल.न्यू के साथ भी) चलाना रूबी 6 एमबी से ऊपर नहीं जाता है। (मैं घड़ी -0 0,1 "ps ax -o comm, rss | grep ruby ​​>>/tmp/q" के साथ परीक्षण कर रहा हूं)। लेकिन आप कोड की नमूना रेखा वास्तव में अच्छी लगती है ;-) –