রিসোর্স ফাঁস: 'ইন' কখনই বন্ধ হয় না


86

নীচের কোডটিতে কেন গ্রহপ আমাকে উষ্ণায়নের "রিসোর্স ফাঁস: 'ইন' কখনই বন্ধ করা হয় না" দেয়?

public void readShapeData() {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter the width of the Rectangle: ");
        width = in.nextDouble();
        System.out.println("Enter the height of the Rectangle: ");
        height = in.nextDouble();

উত্তর:


72

কারণ আপনি আপনার স্ক্যানারটি বন্ধ করেন না

in.close();

40
এটি বন্ধ করে দেবে Scannerএবং সতর্কবার্তাটি নীরব করবে, তবে এটি বন্ধ হবে System.inযা সাধারণত কাঙ্ক্ষিত নয়।
স্টুয়ার্ট কুক

@ স্টুয়ার্টকুক +1 নজর রাখার মতো কিছু।
informatik01

8
কেন আমাদের স্ক্যানার বন্ধ করা দরকার? "রিসোর্স লিক" বলতে কী বোঝায়?
এরান মোরাড

4
@ নোগার্ড: এটি আপনার উত্তরটি সত্যিই সহায়ক is তবে আমি যখন ইনক্লোজ () ব্যবহার করি তখন ... আবার এটির সমাধান দেখানো যায় না .. ব্যতিক্রম পরিচালনা না করে আমার একটি কোড আছে .. ধন্যবাদ
পিসি

4
@ স্টুয়ার্টকুক, আপনি কেন উল্লেখ করতে ভুলে গেছেন যে System.inসাধারণত কেন বন্ধ হওয়া পছন্দসই নয়। এটি কারণ আপনি এটি থেকে আর পড়তে পারবেন না। আই। ই। আপনি উদাহরণস্বরূপ java.util.NoSuchElementException: No line foundকল করার চেষ্টা করলে আপনি পাবেন (new Scanner(System.in)).nextLine()
পেটর বোদনার

55

অন্যরা যেমন বলেছে, আপনাকে আইও ক্লাসে 'ক্লোজ' করতে হবে। আমি যুক্ত করব যে চেষ্টাটি ব্যবহারের জন্য এটি একটি দুর্দান্ত স্পট - অবশেষে কোনও ধরা না দিয়ে ব্লক করুন:

public void readShapeData() throws IOException {
    Scanner in = new Scanner(System.in);
    try {
        System.out.println("Enter the width of the Rectangle: ");
        width = in.nextDouble();
        System.out.println("Enter the height of the Rectangle: ");
        height = in.nextDouble();
    } finally {
        in.close();
    }
}

এটি নিশ্চিত করে যে আপনার স্ক্যানারটি সর্বদা বন্ধ থাকে, যথাযথ সংস্থান পরিষ্কারের গ্যারান্টি দেয়।

সমানভাবে, জাভা 7 বা ততোধিক ক্ষেত্রে, আপনি "রিসোর্স-উইথ রিসোর্স" সিনট্যাক্সটি ব্যবহার করতে পারেন:

try (Scanner in = new Scanner(System.in)) {
    ... 
}

4
রিসোর্স লিক বলতে কী বোঝায় এবং এটি আমাকে কীভাবে প্রভাবিত করবে?
এরান মোরাড

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

ধন্যবাদ এরিক আমি জানি যে আপনি অসীম লুপটিতে স্ট্রিং যুক্ত করে ত্রুটি সৃষ্টি করতে পারেন। আমি নিশ্চিত না যে কোনও স্ক্যানার কীভাবে সেই ত্রুটি ঘটাতে পারে।
এরান মোরাড

4
সম্পদ-চেষ্টা সম্পর্কে কি?
ডেনিস মেং

ধন্যবাদ ডেনিস, যোগ।
এরিক Lindauer

12

এটি ঘটে তা নিশ্চিত করার জন্য আপনার in.close()একটি finallyব্লকে কল দরকার ।

অ্যালিপস ডকুমেন্টেশন থেকে, এখানে কেন এটি এই বিশেষ সমস্যাটিকে ঝাপিয়ে তোলে ( জোর দেওয়া খনি):

ইন্টারফেস java.io.Closeable (JDK 1.5 থেকে) এবং java.lang.AutoCloseable (JDK 1.7) প্রয়োগকারী ক্লাসগুলি বহিরাগত সংস্থানসমূহের প্রতিনিধিত্ব হিসাবে বিবেচিত হয়, যা পদ্ধতিটির কাছাকাছি () ব্যবহার করে বন্ধ করা উচিত, যখন তাদের আর প্রয়োজন হয় না।

Eclipse জাভা সংকলক এই জাতীয় ধরণের কোড ব্যবহার করে এই নীতিটি মেনে চলেন কিনা তা বিশ্লেষণ করতে সক্ষম।

...

সংকলক "রিসোর্স লিক: 'স্ট্রিম' কখনও বন্ধ হয় না" সহ [লঙ্ঘন] পতাকাঙ্কিত করবে।

এখানে সম্পূর্ণ ব্যাখ্যা ।


7

এটি আপনাকে বলছে যে আপনি যে স্ক্যানারটি System.inদিয়ে ইনস্ট্যান্ট করেছিলেন তা বন্ধ করতে হবে Scanner.close()। সাধারণত প্রতিটি পাঠক বন্ধ করে দেওয়া উচিত।

দ্রষ্টব্য যে আপনি যদি বন্ধ করেন তবে আপনি System.inএটি থেকে আর পড়তে পারবেন না। আপনি Consoleক্লাসটি একবার দেখে নিতে পারেন ।

public void readShapeData() {
    Console console = System.console();
    double width = Double.parseDouble(console.readLine("Enter the width of the Rectangle: "));
    double height = Double.parseDouble(console.readLine("Enter the height of the Rectangle: "));
    ...
}

4
নোট যে System.console()Eclipse মাধ্যমে অ্যাপ্লিকেশন চালানোর সময় উপলব্ধ না, যা বিকাশের সময় ঝামেলা হতে পারে।
স্টুয়ার্ট কুক

6

আপনি যদি JDK7 বা 8 ব্যবহার করে থাকেন তবে আপনি রিসোর্স সহ ট্রাই-ক্যাচ ব্যবহার করতে পারেন his এটি স্বয়ংক্রিয়ভাবে স্ক্যানারটি বন্ধ করে দেবে।

try ( Scanner scanner = new Scanner(System.in); )
  {
    System.out.println("Enter the width of the Rectangle: ");
    width = scanner.nextDouble();
    System.out.println("Enter the height of the Rectangle: ");
    height = scanner.nextDouble();
  }
catch(Exception ex)
{
    //exception handling...do something (e.g., print the error message)
    ex.printStackTrace();
}

লক্ষ্য করুন যে ক্যাচ ক্লজটি বাধ্যতামূলক নয়। আপনি যদি কেবলমাত্র ব্যতিক্রম ঘটায়ও সম্পদটি বন্ধ রয়েছে তা নিশ্চিত করতে চান তবে অপের মূল কোড অনুসারে ব্যতিক্রমের চিকিত্সাটি ছেড়ে যান (যথা, মোটেও ধরা পড়ে না) আপনি কেবল tryপ্রদর্শিত হিসাবে ব্যবহার করতে পারেন এবং একটি catchধারা ব্যবহার করতে পারেন না ।
ব্যবহারকারী 118967

5
// An InputStream which is typically connected to keyboard input of console programs

Scanner in= new Scanner(System.in);

উপরের লাইনটি আর্গুমেন্ট System.in সহ স্ক্যানার শ্রেণির কনস্ট্রাক্টরকে অনুরোধ করবে এবং সদ্য নির্মিত নির্মিত বস্তুর একটি রেফারেন্স ফিরিয়ে দেবে।

এটি একটি ইনপুট স্ট্রিমের সাথে সংযুক্ত যা কীবোর্ডের সাথে সংযুক্ত, সুতরাং এখন রান-টাইমে আপনি প্রয়োজনীয় অপারেশন করতে ব্যবহারকারী ইনপুট নিতে পারেন।

//Write piece of code 

স্মৃতি ফাঁস দূর করতে -

in.close();//write at end of code.


3

সংযোজন private static Scanner in;আসলেই সমস্যার সমাধান করে না, এটি কেবল সতর্কতাটি পরিষ্কার করে। স্ক্যানারটিকে স্থির করার অর্থ এটি চিরকাল খোলা থাকে (বা ক্লাসটি লোড না হওয়া অবধি, যা প্রায় "চিরকাল") is সংকলকটি আপনাকে আর কোনও সতর্কতা দেয় না, যেহেতু আপনি তাকে "চিরতরে খোলা রাখুন" বলেছিলেন। তবে এটি আপনি যা চাইছিলেন তা নয়, যেহেতু আপনার আর কোনও প্রয়োজন না হওয়ার সাথে সাথে আপনার উত্সগুলি বন্ধ করা উচিত।

এইচটিএইচ, ম্যানফ্রেড


2

সাধারণত, I / O এর সাথে সম্পর্কিত ক্লাসগুলির উদাহরণগুলি শেষ করার পরে আপনার বন্ধ করা উচিত। সুতরাং আপনার কোডের শেষে আপনি যুক্ত করতে পারেন in.close()


2
private static Scanner in;

আমি প্রাইভেট স্ট্যাটিক স্ক্যানার ক্লাস ভেরিয়েবল হিসাবে ঘোষণা করে এটি ঠিক করেছি। কেন এটি স্থির করে তা নিশ্চিত নয় তবে গ্রহনের প্রস্তাব আমিই করেছি।


4
আপনি সতর্কবার্তাটি নিঃশব্দ করেছেন তবে তৈরি করেছেন রিসোর্স লিক
zacheusz

1

স্ক্যানারটি বন্ধ করা উচিত। রিডারস এবং অ্যাভিড মেমরি ফাঁস মুক্ত করার জন্য পাঠক, স্ট্রিমগুলি ... এবং এই ধরণের অবজেক্টগুলি বন্ধ করা একটি ভাল অনুশীলন; এবং অবশেষে ব্লক করে এটি নিশ্চিত করার জন্য যে এই বিষয়গুলি পরিচালনা করার সময় কোনও ব্যতিক্রম ঘটেছে এমনকি যদি তারা বন্ধ হয়ে যায় make


এই উত্তরটি আসলে ওপিকে এটি কেন বন্ধ করতে হবে তা জানতে সহায়তা করে। অবশ্যই, তিনি দস্তাবেজটি পড়তে এবং " scanner.close()" দেখতে পাবেন , তবে এই উত্তরটি তাকে / তাকে কী ঘটছে তা বুঝতে সহায়তা করে। + 1
হাইপারনিউট্রিনো

1

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



-1
in.close();
scannerObject.close(); 

এটি Scannerসতর্কতা বন্ধ এবং বন্ধ করবে।

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