রুবিতে ফাইল পড়ার সমস্ত সাধারণ উপায় কী কী?
উদাহরণস্বরূপ, এখানে একটি পদ্ধতি:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
আমি জানি রুবি অত্যন্ত নমনীয়। প্রতিটি পদ্ধতির সুবিধা / ত্রুটিগুলি কী কী?
রুবিতে ফাইল পড়ার সমস্ত সাধারণ উপায় কী কী?
উদাহরণস্বরূপ, এখানে একটি পদ্ধতি:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
আমি জানি রুবি অত্যন্ত নমনীয়। প্রতিটি পদ্ধতির সুবিধা / ত্রুটিগুলি কী কী?
উত্তর:
File.open("my/file/path", "r") do |f|
f.each_line do |line|
puts line
end
end
# File is closed automatically at end of block
উপরের মত স্পষ্টতই ফাইলটি বন্ধ করাও সম্ভব ( open
এটি আপনার জন্য বন্ধ করে দেওয়ার জন্য একটি ব্লক পাস করুন ):
f = File.open("my/file/path", "r")
f.each_line do |line|
puts line
end
f.close
foreach
পরিবর্তে ব্যবহার করুন open
এবং each_line
ব্লকটি সরবরাহ করুন।
f.each { |line| ... }
এবং f.each_line { |line| ... }
একই আচরণ বলে মনে হচ্ছে (কমপক্ষে রুবি ২.০.০ এ)।
ফাইলটি খুব বেশি দীর্ঘ না হলে সবচেয়ে সহজ উপায় হ'ল:
puts File.read(file_name)
প্রকৃতপক্ষে, IO.read
বা File.read
স্বয়ংক্রিয়ভাবে ফাইলটি বন্ধ করুন, সুতরাং কোনও File.open
ব্লক ব্যবহার করার দরকার নেই ।
IO.read
বা File.read
স্বয়ংক্রিয়ভাবে ফাইলটি বন্ধ করে দিন, যদিও আপনার শব্দটি এটিকে শোনায় এমন করে তোলে যা না।
"স্লারপিং" ফাইলগুলি থেকে সাবধান থাকুন। আপনি যখন একবারে পুরো ফাইলটি মেমরিতে পড়েন তখনই।
সমস্যাটি হ'ল এটি ভাল স্কেল করে না। আপনি যুক্তিসঙ্গত আকারের ফাইল সহ কোড বিকাশ করতে পারেন, তারপরে এটিকে উত্পাদনে রাখুন এবং হঠাৎ আপনি গিগাবাইটে পরিমাপ করা ফাইলগুলি পড়ার চেষ্টা করছেন এবং মেমরিটি পড়ার এবং বরাদ্দ দেওয়ার চেষ্টা করার সাথে সাথে আপনার হোস্ট হিমশীতল হয়ে উঠছে।
লাইন বাই লাইন আই / ও খুব দ্রুত এবং প্রায় সবসময় স্লুর্পিংয়ের মতো কার্যকর। এটি আশ্চর্যজনকভাবে আসলে দ্রুত।
আমি ব্যবহার করতে চাই:
IO.foreach("testfile") {|x| print "GOT ", x }
অথবা
File.foreach('testfile') {|x| print "GOT", x }
ফাইলটি আইও থেকে উত্তরাধিকার সূত্রে প্রাপ্ত foreach
এবং আইওতে রয়েছে, সুতরাং আপনি যে কোনওটি ব্যবহার করতে পারেন।
read
বনাম লাইন বাই লাইন I / O এর মাধ্যমে বড় ফাইলগুলি পড়ার চেষ্টা করার প্রভাবের কিছুটা বেনমার্ক রয়েছে যা "ফাইলকে" স্লুরপিং "একটি ভাল অনুশীলন নয় কেন? "।
আপনি একবারে ফাইলটি পড়তে পারেন:
content = File.readlines 'file.txt'
content.each_with_index{|line, i| puts "#{i+1}: #{line}"}
যখন ফাইলটি বড় হয় বা বড় হতে পারে তবে সাধারণত এটি লাইন-লাইন প্রক্রিয়াকরণ করা ভাল:
File.foreach( 'file.txt' ) do |line|
puts line
end
কখনও কখনও আপনি ফাইল হ্যান্ডেল অ্যাক্সেস করতে চান বা নিজেই পড়েন:
File.open( 'file.txt' ) do |f|
loop do
break if not line = f.gets
puts "#{f.lineno}: #{line}"
end
end
বাইনারি ফাইলগুলির ক্ষেত্রে, আপনি নীল-বিভাজক এবং একটি ব্লক আকার নির্দিষ্ট করতে পারেন:
File.open('file.bin', 'rb') do |f|
loop do
break if not buf = f.gets(nil, 80)
puts buf.unpack('H*')
end
end
অবশেষে আপনি এটি কোনও ব্লক ছাড়াই করতে পারেন, উদাহরণস্বরূপ একসাথে একাধিক ফাইল প্রক্রিয়াকরণ করার সময়। সেক্ষেত্রে ফাইলটি অবশ্যই স্পষ্টভাবে বন্ধ করতে হবে (@ আইটিনোমের মন্তব্য অনুসারে উন্নত):
begin
f = File.open 'file.txt'
while line = f.gets
puts line
end
ensure
f.close
end
তথ্যসূত্র: ফাইল এপিআই এবং আইও এপিআই ।
while
পরিবর্তে loop
ব্যবহার ensure
এবং ফাইলটি বন্ধ হয়ে যায় কিনা তা নিশ্চিত করার জন্য যদি কোনও ব্যতিক্রম উত্থাপিত হয় তবে তা ব্যবহার করার পরামর্শ দিতে পারি । এই মত (প্রতিস্থাপন নতুন লাইন দিয়ে আধা কোলন): begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
।
একটি সহজ পদ্ধতি ব্যবহার করা হয় readlines
:
my_array = IO.readlines('filename.txt')
ইনপুট ফাইলের প্রতিটি লাইন অ্যারেতে প্রবেশ করবে। পদ্ধতিটি আপনার জন্য ফাইলটি খোলার এবং বন্ধ করতে পরিচালনা করে।
read
বা কোনও ভেরিয়েন্ট হিসাবে এটি পুরো ফাইলটিকে মেমরিতে টানবে, যা ফাইল উপলব্ধ মেমরির চেয়ে বড় হলে বড় সমস্যা তৈরি করতে পারে। এছাড়াও এটি একটি অ্যারে হওয়ায় রুবিকে অ্যারে তৈরি করতে হবে, প্রক্রিয়াটি অতিরিক্তভাবে ধীর করে ফেলবে।
file_content = File.read('filename with extension');
puts file_content;
আমি সাধারণত এটি করি:
open(path_in_string, &:read)
এটি আপনাকে স্ট্রিং অবজেক্ট হিসাবে পুরো পাঠ্যটি দেবে। এটি কেবল রুবি ১.৯ এর অধীনে কাজ করে।
আপনার_ফিল.লগ বা .txt থেকে শেষ এন লাইনগুলি ফিরিয়ে দিন
path = File.join(Rails.root, 'your_folder','your_file.log')
last_100_lines = `tail -n 100 #{path}`
আরও কার্যকর উপায় অপারেটিং সিস্টেমের কার্নেলটিকে একটি ফাইল খোলার জন্য জিজ্ঞাসা করে স্ট্রিমিং করছে, তারপরে এটি থেকে বাইটগুলি কিছুটা অল্প করে পড়ুন। রুবির প্রতি লাইনে কোনও ফাইল পড়ার সময়, ফাইলগুলি একবারে 512 বাইট ফাইল থেকে নেওয়া হয় এবং তার পরে "লাইনে" বিভক্ত হয়।
ফাইলের সামগ্রীতে বাফারিংয়ের মাধ্যমে, লজিকাল খণ্ডগুলিতে ফাইলটি বিভক্ত করার সময় I / O কলগুলির সংখ্যা হ্রাস পাবে।
উদাহরণ:
পরিষেবা ক্লাব হিসাবে এই অ্যাপ্লিকেশনটিতে এই শ্রেণিটি যুক্ত করুন:
class MyIO
def initialize(filename)
fd = IO.sysopen(filename)
@io = IO.new(fd)
@buffer = ""
end
def each(&block)
@buffer << @io.sysread(512) until @buffer.include?($/)
line, @buffer = @buffer.split($/, 2)
block.call(line)
each(&block)
rescue EOFError
@io.close
end
end
এটিকে কল করুন এবং :each
পদ্ধতিটিকে একটি ব্লক পাস করুন :
filename = './somewhere/large-file-4gb.txt'
MyIO.new(filename).each{|x| puts x }
এই বিস্তারিত পোস্টে এটি সম্পর্কে এখানে পড়ুন:
রুবি ম্যাজিক স্লুরপিং এবং স্ট্রিমিং ফাইলগুলি অ্যাপসিসিনাল দ্বারা
content = `cat file`
আমি মনে করি এই পদ্ধতিটি সবচেয়ে "অস্বাভাবিক" এক। হতে পারে এটি এক ধরণের কৌতুকজনক, তবে cat
ইনস্টল করা থাকলে এটি কাজ করে ।
content = File.read(filename)