রুবির ফাইল.ওপেন এবং f.close এর প্রয়োজনীয়তা


92

বেশিরভাগ প্রোগ্রামিং ভাষায় এটি সাধারণ জ্ঞান যে ফাইলগুলির সাথে কাজ করার প্রবাহটি উন্মুক্ত-ব্যবহার-বন্ধ। তবুও আমি অনেকবার রুবি কোডগুলিতে ফাইলের ওপেন কলগুলি তুলনা না করে দেখতে পেয়েছি এবং তবুও আমি জ্ঞানের এই রত্নটি রুবি ডক্সে পেয়েছি :

আই / ও স্ট্রীমগুলি আবর্জনা সংগ্রহকারী দ্বারা দাবি করা হলে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়।

অন্ধকারযুক্ত ও বন্ধুত্বপূর্ণ রিক ইস্যুটি গ্রহণ করে:
[ ১ [ :१২ ] হ্যাঁ, এবং এগুলিও, ফাইল বর্ণনাকারীর সংখ্যা সাধারণত ওএস দ্বারা সীমাবদ্ধ থাকে
[১ 17:২৯] আমি ধরে নিয়েছি যে আবর্জনা সংগ্রহকারী পরিষ্কার করার আগে আপনি সহজেই ফাইল ফাইল বর্ণনাকারীর বাইরে চলে যেতে পারেন আপ এই ক্ষেত্রে, আপনি এগুলি নিজেই বন্ধ করতে চান। "আবর্জনা সংগ্রহকারী দ্বারা দাবি করা।" এর অর্থ হ'ল জিসি ভবিষ্যতে কোনও সময় কাজ করে। এবং এটা ব্যয়বহুল। স্পষ্টত ফাইল বন্ধ করার জন্য অনেক কারণ।

  1. আমাদের কি স্পষ্টভাবে বন্ধ করা দরকার?
  2. যদি হ্যাঁ হয় তবে জিসি অটোক্লোজ করে কেন?
  3. তা না হলে বিকল্প কেন?

4
আপনার 'সাধারণ জ্ঞান' পুরানো হয়ে গেছে যেহেতু ধ্বংসকারীদের আবিষ্কার হয়েছিল।
মেগার

4
@ মাঝারি: ধ্বংসকারীদের উদ্ভাবন কবে হয়েছিল?
অ্যান্ড্রু গ্রিম

কেবলমাত্র একটি দ্রষ্টব্য: ফাইল বর্ণনাকারীরা সীমাবদ্ধ থাকলেও লিনাক্সে কমপক্ষে সীমাটি বেশ বেশি।
লিনাকোনিওস

4
@ লিনাকোসিওস: আমার উবুন্টু ১২.০৪ তে $ ulimit -n => 1024আপনি কেবলমাত্র কিছু সাধারণ কাজ করলে এটি কেবল উচ্চ। খারাপ অভ্যাস একদিন বড় সমস্যা সৃষ্টি করবে!
এইচভিএনএসইভিং

উত্তর:


133

আমি রুবি কোডের সাথে মেলে না এমন File.openকলগুলিতে অনেকবার দেখেছি

আপনি কি একটি উদাহরণ দিতে পারেন? আমি কেবল কখনও দেখতে পাই যে নবাবিদের লিখিত কোডে যাদের "বেশিরভাগ প্রোগ্রামিং ভাষায় সাধারণ জ্ঞানের অভাব যে ফাইলগুলির সাথে কাজ করার প্রবাহটি উন্মুক্ত-ব্যবহার-বন্ধ"।

অভিজ্ঞ রুবিস্টরা হয় স্পষ্টভাবে তাদের ফাইলগুলি বন্ধ করে দেয় বা আরও মূ id়ভাবে, এর ব্লক ফর্মটি ব্যবহার করে File.open, যা স্বয়ংক্রিয়ভাবে আপনার জন্য ফাইলটি বন্ধ করে দেয়। এর বাস্তবায়নটি মূলত এরকম কিছু দেখায়:

def File.open(*args, &block)
  return open_with_block(*args, &block) if block_given?
  open_without_block(*args)
end

def File.open_without_block(*args)
  # do whatever ...
end

def File.open_with_block(*args)
  yield f = open_without_block(*args)
ensure
  f.close
end

স্ক্রিপ্টগুলি একটি বিশেষ কেস। স্ক্রিপ্টগুলি সাধারণত এত সংক্ষিপ্তভাবে চালিত হয় এবং খুব কম ফাইল বর্ণনাকারী ব্যবহার করে যে এগুলি বন্ধ করে দেওয়া সহজভাবে বোঝায় না, কারণ স্ক্রিপ্টটি প্রস্থান করার সময় অপারেটিং সিস্টেম যেভাবেই এগুলি বন্ধ করে দেবে।

আমাদের কি স্পষ্টভাবে বন্ধ করা দরকার?

হ্যাঁ.

যদি হ্যাঁ হয় তবে জিসি অটোক্লোজ করে কেন?

কারণ এটি বস্তুটি সংগ্রহ করার পরে, আপনার আর ফাইলটি বন্ধ করার কোনও উপায় নেই এবং সুতরাং আপনি ফাইল বর্ণনাকারীদের ফাঁস করবেন।

দ্রষ্টব্য যে এটি আবর্জনা সংগ্রহকারী নয় যা ফাইলগুলি বন্ধ করে দেয়। আবর্জনা সংগ্রহকারী কোনও বস্তুর এটি সংগ্রহের আগে কেবল কোনও চূড়ান্তকরণকারীকে কার্যকরভাবে কার্যকর করে। এটি ঠিক তাই ঘটে যে Fileক্লাস একটি ফাইনালাইজার সংজ্ঞায়িত করে যা ফাইলটি বন্ধ করে দেয়।

তা না হলে বিকল্প কেন?

কারণ নষ্ট মেমরিটি সস্তা, তবে নষ্ট ফাইল বর্ণনাকারী নয়। অতএব, কোনও ফাইল বর্ণনাকারীর জীবনকালকে কিছুটা মেমরির জীবনকালের সাথে বেঁধে রাখার কোনও মানে হয় না।

আবর্জনা সংগ্রহকারী কখন চলবে তা আপনি সহজেই অনুমান করতে পারবেন না । এটি আদৌ চলবে কিনা তা আপনি পূর্বাভাসও দিতে পারবেন না : যদি আপনি কখনও স্মৃতি থেকে সরে না যান, আবর্জনা সংগ্রহকারী কখনও চালাবেন না, তাই ফাইনালাইজারটি কখনও চালাবেনা, তাই ফাইলটি কখনও বন্ধ হবে না।


4
github.com/isaac/sunspot/blob/sel/sunspot/lib/sunspot/… +23 (যদিও এর কার্নেল # টি উন্মুক্ত এবং মূলত এটির HTTP দিকের জন্য ব্যবহৃত হয়েছে, তবুও আমি এটি স্থানীয় ফাইল পাথ প্যারামিটার দিয়ে পৌঁছেছি। ..; আমি এখনও প্যাচ করার অনুরোধ করছি & অনুরোধ-টান), github.com/jnicklas/carrierwave Ctrl + f "File.open" (এটি উদাহরণ হিসাবে দেওয়া হয়েছে, তবে একটি খারাপ উপায়ে ...), এবং বেশ কয়েকটি অন্য জায়গাগুলি আমার মনে নেই। আমার প্রকল্পগুলিতে স্থিতিশীলতার প্রয়োজনীয়তার কারণে এই সমস্যাটি নিয়ে আমি একটি গো-মাংস রেখেছি ..
clyfe

4
এই উদাহরণস্বরূপ, উদ্ধার ব্লকের ভিতরে থাকা উচিত? যদি উত্থাপন বলা হয় এবং ব্যতিক্রম না হয় তবে এটি কেবল রানটাইম ত্রুটি ছুঁড়ে ফেলবে না?
জেফ স্টোরি

@ জেফস্টোরী: চমৎকার ধরা! 17 মাস কারও কারও নজরে নেই ...
Jörg W Mittag

@ জার্গডব্লিউমিত্যাগ এবং এখন আরও 17 মাস স্থির হয়নি: পিআই অনুমান করে যে এখানে মূল বিষয়টি ensure, rescueএবং raiseএটি মোটেই প্রয়োজনীয় নয়।
কেএল -7

আমি মনে করি আপনি ensureছাড়া থাকতে পারে না rescue। এবং আপনি কেবল চুপচাপ ব্যতিক্রমটি গিলে ফেলতে পারবেন না, ফাইলটি বন্ধ করে দেওয়ার পরে আপনাকে এটিকে কলারের কাছে প্রচার করতে হবে। যাইহোক, আমাকে '15 :-D- এ আবার স্মরণ করিয়ে দিন
জার্গ ডব্লু মিটাগ

72

আপনার ব্যবহারের পরে ফাইল বর্ণনাকারীদের সর্বদা বন্ধ করা উচিত, এটি এটি ফ্লাশও করবে। প্রায়শই লোকেরা ফাইল বর্ণনাকারী আজীবন পরিচালনা করতে ব্লকগুলির সাথে ফাইল.ওপেন বা সমমানের পদ্ধতি ব্যবহার করে । উদাহরণ স্বরূপ:

File.open('foo', 'w') do |f|
    f.write "bar"
end

এই উদাহরণে ফাইলটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়।


ভাল যুক্তি. আমি একটি স্ক্রিপ্টে একটি বাগ ট্র্যাক করেছি যা ফাইল.ক্লোজ কল করে না। ফলস্বরূপ শেষ লাইনটি এখন থেকে কিছু ফাইলের মধ্যে হারিয়ে যাবে।
এরওয়ান লেগ্রান্ড

বকেয়া। আমি এই কৌশলটি কখনই জানতাম না। অনেকটা জাভা-8 এর মতো। ধন্যবাদ.
স্নেগতা

2

Http://ruby-doc.org/core-2.1.4/File.html#method-c-open অনুসারে

কোনও সম্পর্কিত ব্লক ছাড়াই, ফাইল.ওপেন :: নতুন এর সমার্থক শব্দ। Alচ্ছিক কোড ব্লক যদি দেওয়া হয় তবে এটি খোলা ফাইলটিকে একটি আর্গুমেন্ট হিসাবে পাস করা হবে এবং ব্লকটি বন্ধ হয়ে গেলে ফাইল অবজেক্টটি স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে। ব্লকের মান ফাইল.ওপেন থেকে ফিরে আসবে।

সুতরাং, ব্লকটি বন্ধ হয়ে গেলে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে : ডি


1
  1. হ্যাঁ
  2. যদি আপনি না করেন তবে বা অন্য কোনও ব্যর্থতা থাকলে
  3. দেখুন 2।

-3

আমরা File.read()রুবিতে ফাইলটি পড়তে ফাংশনটি ব্যবহার করতে পারি ..... যেমন,

file_variable = File.read("filename.txt")

এই উদাহরণে file_variableসেই ফাইলটির পুরো মান থাকতে পারে ....

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.