Class.getResource () এবং ClassLoader.getResource () এর মধ্যে পার্থক্য কী?


194

আমি ভাবছি কি পার্থক্য মধ্যে Class.getResource()এবং ClassLoader.getResource()?

সম্পাদনা: আমি বিশেষত জানতে চাই যে কোনও ক্যাচিং ফাইল / ডিরেক্টরি স্তরের সাথে জড়িত কিনা। "ক্লাস সংস্করণে ডিরেক্টরি তালিকাভুক্ত রয়েছে?"

AFAIK নিম্নলিখিত নিম্নলিখিত প্রয়োজনীয়ভাবে করা উচিত, কিন্তু তারা না:

getClass().getResource() 
getClass().getClassLoader().getResource()

আমি এটি আবিষ্কার করেছি যখন কিছু রিপোর্ট প্রজন্মের কোডের সাথে ফিড করে যা WEB-INF/classes/সেই ডিরেক্টরিতে বিদ্যমান ফাইল থেকে একটি নতুন ফাইল তৈরি করে । ক্লাস থেকে পদ্ধতিটি ব্যবহার করার সময়, আমি সেখানে ব্যবহৃত ফাইলগুলি ব্যবহার করে ব্যবহারের সময় সন্ধান করতে পারতাম getClass().getResource(), তবে নতুন নির্মিত ফাইলটি আনার চেষ্টা করার সময় আমি একটি নাল বস্তুটি পেয়েছি। ডিরেক্টরি ব্রাউজ করা পরিষ্কারভাবে দেখায় যে নতুন ফাইল রয়েছে। ফাইলের নামগুলি "/myFile.txt" এর মতো একটি ফরোয়ার্ড স্ল্যাশ দিয়ে প্রম্পেন্ড করা হয়েছিল।

ClassLoaderসংস্করণ getResource()অন্যদিকে উত্পন্ন ফাইল খুঁজে পাইনি। এই অভিজ্ঞতা থেকে দেখে মনে হয় যে ডিরেক্টরি তালিকা কিছুটা কেচিং চলছে। আমি কি ঠিক আছি, এবং যদি তাই হয় তবে এই নথিটি কোথায়?

থেকে এপিআই ডক্স উপরClass.getResource()

প্রদত্ত নামের সাথে একটি সংস্থান খুঁজে পায়। প্রদত্ত শ্রেণীর সাথে সম্পর্কিত সংস্থানগুলির সন্ধানের নিয়মগুলি শ্রেণীর সংজ্ঞায়িত শ্রেণি লোডার দ্বারা প্রয়োগ করা হয়। এই পদ্ধতিটি এই বস্তুর শ্রেণি লোডারকে প্রতিনিধিত্ব করে। যদি এই বস্তুটি বুটস্ট্র্যাপ শ্রেণীর লোডার দ্বারা লোড করা হয়, তবে পদ্ধতিটি ClassLoader.getSystemResource (java.lang.String) এর প্রতিনিধিত্ব করে।

আমার কাছে, এটি পড়ছে "Class.getResource সত্যিই তার নিজস্ব শ্রেণি লোডারের getResource () কল করছে"। যা করা একই হবে getClass().getClassLoader().getResource()। তবে তা অবশ্যই হয় না। কেউ দয়া করে আমাকে এই বিষয়ে কিছু আলোকসজ্জা সরবরাহ করতে পারেন?

উত্তর:


6

কোনও ক্যাশে চলছে কিনা এই প্রশ্নের উত্তর দিতে।

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

তবে: আমি বেশ কয়েকটি মাভেন মডিউল এবং ওয়েব প্রকল্পগুলির একে অপরের উপর নির্ভরশীলতা নিয়ে একটি প্রকল্পে কাজ করছি। আমি ওয়েব প্রকল্পগুলি সংকলন ও পরিচালনা করতে আমার আইডিই হিসাবে ইন্টেলিজিকে ব্যবহার করছি।

আমি লক্ষ্য করেছি যে উপরেরটি আর সত্য বলে মনে হচ্ছে না, কারণ যে ফাইলটি আমার বোঝা হচ্ছিল তা এখন একটি পাত্রে বেক করা হয় এবং নির্ভরযোগ্য ওয়েব প্রকল্পে স্থাপন করা হয়। আমার লক্ষ্য ফোল্ডারে ফাইলটি পরিবর্তন করার চেষ্টা করার পরে আমি কেবল এটি লক্ষ্য করেছি, কোনও লাভ হয়নি। এটি দেখে মনে হচ্ছে যেন সেখানে ক্যাশে চলছে।


আমিও মাভেন এবং ইন্টেলিজিকে ব্যবহার করেছি, সুতরাং এটি এমন পরিবেশের সাথে উত্তর যা আমার সাথে সান্নিধ্যের সাথে মেলে এবং প্রশ্নের # 2 এর যুক্তিসঙ্গত ব্যাখ্যা রয়েছে।
অলিগোফ্রেন

249

Class.getResourceশ্রেণীর প্যাকেজের সাথে তুলনামূলকভাবে আচরণ করা "আপেক্ষিক" সংস্থান নাম নিতে পারে। বিকল্পভাবে আপনি একটি শীর্ষস্থানীয় স্ল্যাশ ব্যবহার করে একটি "পরম" সংস্থান নাম উল্লেখ করতে পারেন। শ্রেণিবোর্ড সংস্থান পথ সর্বদা নিরঙ্কুশ বলে মনে করা হয়।

সুতরাং নিম্নলিখিতটি মূলত সমতুল্য:

foo.bar.Baz.class.getResource("xyz.txt");
foo.bar.Baz.class.getClassLoader().getResource("foo/bar/xyz.txt");

এবং এগুলিও (তবে তারা উপরের থেকে আলাদা):

foo.bar.Baz.class.getResource("/data/xyz.txt");
foo.bar.Baz.class.getClassLoader().getResource("data/xyz.txt");

সুস্পষ্ট উদাহরণ সহ চমৎকার উত্তর। যদিও পোস্টটি আসলে দুটি প্রশ্নের উত্তর পাওয়ার জন্যই হয়েছিল, আমি এখন দেখছি যে দ্বিতীয় প্রশ্নগুলি গোপনীয়। কিভাবে / কিনা আমি পোস্ট এই প্রতিফলিত আপডেট করা উচিত, কিন্তু কি আমি দ্বিতীয় জানতে চাই এই (পরবর্তী মন্তব্য) হয় বেশ অনিশ্চিত:
oligofren থেকে

2
ক্লাস.জেট রিসোর্স () সংস্করণে কি কোনও ধরণের ক্যাশে চলছে? আমার বিশ্বাসের কারণেই এটি কিছু জ্যাস্পার রিপোর্টগুলির প্রজন্ম: আমরা জ্যাস্পার এক্সএমএল ফাইল আনার জন্য getClass ()। GetResource ("/ aDocament.jrxml") ব্যবহার করি। একটি বাইনারি জেস্পার ফাইল একই ডিরেক্টরিতে উত্পাদিত হয় । getClass ()। getResource ("/ aDocament.jasper") এটি সন্ধান করতে সক্ষম নয়, যদিও এটি একই স্তরে (ইনপুট ফাইল) স্পষ্টতই নথিগুলি খুঁজে পেতে পারে। এখানেই ClassLoader.getResource () সহায়ক হিসাবে প্রমাণিত হয়েছে, কারণ মনে হয় এটি ডিরেক্টরি তালিকার ক্যাচিং ব্যবহার করে না। তবে আমি এটিতে দলিল খুঁজে পাচ্ছি না।
অলিগোফ্রেন 16

2
@ অলিগফ্রেন: হুম ... আমি আশা করি না ক্লাস.সেট রিসোর্স () সেখানে কোনও ক্যাচিং করবে ...
জোন স্কিট

1
@JonSkeet কেন this.getClass().getClassLoader().getResource("/");নাল ফিরে? এটির মতো হওয়া উচিত নয়this.getClass().getClassLoader().getResource(".");
আসিফ মুশতাক

@ অজানা: আমি মনে করি আপনার সম্ভবত এটি সম্পর্কে একটি নতুন প্রশ্ন করা উচিত।
জন স্কিটি

22

প্রথম কলটি .classক্লাসপথের মূলের সাথে সম্পর্কিত যখন অনুসন্ধান করে তখন ফাইলটির সাথে সম্পর্কিত।

এই জাতীয় সমস্যাগুলি ডিবাগ করতে, আমি ইউআরএল মুদ্রণ করি:

System.out.println( getClass().getResource(getClass().getSimpleName() + ".class") );

3
আমি মনে করি "ক্লাসলোডার রুট" "ক্লাসপাথ রুট" এর চেয়ে আরও নির্ভুল হবে - কেবল বাছাই করা।
জন স্কিটি

4
উভয়ই "পরম পথগুলি" অনুসন্ধান করতে পারেন যদি ফাইলের নাম "/" দ্বারা চালিত করা হয়
অলিগোফ্রেন

2
আকর্ষণীয় ... আমি getClass ()। GetResource ("/ someAbsPath") /path/to/mylib.jar!/someAbsPath এবং getClass ()। GetClassLoafer () প্রকারের URL টি পেয়েছি এমন একটি ক্ষেত্রে আমি হিট করছি get / someAbsPath ") প্রত্যাবর্তন শূন্য ... সুতরাং" শ্রেণীবদ্ধার মূল "খুব ভাল সংজ্ঞায়িত ধারণা বলে মনে হচ্ছে না ...
পিয়ের হেনরি


8
@ পিয়ারহেনরি: getClassLoader().getResource("/...")সর্বদা ফিরে আসে null- ক্লাসলোডার /পথ থেকে শীর্ষস্থান সরিয়ে দেয় না , তাই অনুসন্ধান সর্বদা ব্যর্থ হয়। ক্লাসপাথের সাথে সম্পর্কিত একটি নিখুঁত পাথ হিসাবে কেবল getClass().getResource()একটি সূচনা পরিচালনা /করে।
অ্যারন দিগুল্লা

17

চশমা এটি তাকান ছিল:

শ্রেণীর গেটআরসোর্স () - ডকুমেন্টেশনে পার্থক্য বর্ণনা করা হয়েছে:

এই পদ্ধতিটি উত্সের নামটিতে এই পরিবর্তনগুলি করার পরে, তার শ্রেণি লোডারকে কলটি উপস্থাপন করে: যদি উত্সের নাম "/" দিয়ে শুরু হয়, এটি অপরিবর্তিত; অন্যথায়, "রূপান্তর করার পরে প্যাকেজের নামটি সংস্থার নামের সাথে যুক্ত করা হয়।" প্রতি "/". যদি এই বস্তুটি বুটস্ট্র্যাপ লোডার দ্বারা লোড করা হত, কলটি ClassLoader.getSystemResource এ দেওয়া হবে।


2
এটি ডিরেক্টরি তালিকাও ক্যাশে করে কিনা সে সম্পর্কে আপনার কোনও তথ্য আছে? প্রথমে কোনও ইনপুট ফাইলটি অনুসন্ধান করার সময় এবং একই ডিরেক্টরিতে এটি ব্যবহার করে কোনও ফাইল তৈরি করার সময় এই দুটি পদ্ধতির মধ্যে প্রধান পার্থক্য ছিল। ক্লাস সংস্করণ এটি খুঁজে পায় নি, ক্লাসলুডার সংস্করণটি করেছে (উভয়ই "/file.txt" ব্যবহার করে)।
অলিগোফ্রেন 16

11

এই সমস্ত উত্তর এখানে এবং সেই সাথে এই প্রশ্নের উত্তরগুলিও পরামর্শ দেয় যে "/foo/bar.properties" এর মতো পরম URL গুলি লোড করা class.getResourceAsStream(String)এবং দ্বারা একই আচরণ করা হবে class.getClassLoader().getResourceAsStream(String)। এটি ক্ষেত্রে নয়, কমপক্ষে আমার টমক্যাট কনফিগারেশন / সংস্করণে নেই (বর্তমানে 7.0.40)।

MyClass.class.getResourceAsStream("/foo/bar.properties"); // works!  
MyClass.class.getClassLoader().getResourceAsStream("/foo/bar.properties"); // does NOT work!

দুঃখিত, আমার কাছে কোনও সন্তোষজনক ব্যাখ্যা নেই, তবে আমি অনুমান করি যে টমক্যাট ক্লাসলোডারদের সাথে নোংরা কৌশল এবং তার কালো যাদু করে এবং পার্থক্যের কারণ করে। আমি সবসময় class.getResourceAsStream(String)অতীতে ব্যবহার করেছি এবং কোনও সমস্যা হয়নি।

পিএস: আমি এটি এখানে পোস্ট করেছি


এই আচরণটি টমক্যাটের একটি বাগ হিসাবে দেখা গেছে যা সংস্করণ 8-এ স্থির করা হয়েছিল I আমি এই প্রশ্নের সম্পর্কে
লর্ডআফ দ্য পিপস

2

Class.getResourcesক্লাসলোডার দ্বারা সংস্থানটি পুনরুদ্ধার করবে যা বস্তুটি লোড করে। যদিও ClassLoader.getResourceরিসোর্স classloader নিদিষ্ট ব্যবহার পুনরুদ্ধার হবে।


0

আমি ইনপুট 1 টেক্সট থেকে পড়ার চেষ্টা করেছি যা আমার এক প্যাকেজের ভিতরে ছিল যা ক্লাসটি পড়ার চেষ্টা করছিল with

নিম্নলিখিত কাজগুলি:

String fileName = FileTransferClient.class.getResource("input1.txt").getPath();

System.out.println(fileName);

BufferedReader bufferedTextIn = new BufferedReader(new FileReader(fileName));

সর্বাধিক গুরুত্বপূর্ণ অংশটি ছিল আপনি getPath()স্ট্রিং ফর্ম্যাটে সঠিক পথের নামটি চাইলে কল করা । ব্যবহার করবেন নাtoString() কারণ এটি কিছু অতিরিক্ত ফর্ম্যাটিং পাঠ্য যুক্ত করবে যা ফাইলের নামটি পুরোপুরি মেস করবে (আপনি এটি চেষ্টা করে দেখতে পারেন এবং প্রিন্ট আউট দেখতে পারেন)।

এটি ডিবাগ করতে ২ ঘন্টা ব্যয় করেছে ... :(


Class.getResourceAsStream () সম্পর্কে কী ?
লু 55

সংস্থানগুলি ফাইল নয়। এগুলি JAR বা WAR ফাইল থেকে প্যাক করা নাও হতে পারে এবং যদি না হয় FileReaderবা FileInputStreamতাদের অ্যাক্সেসের জন্য ব্যবহার করা যায় না। উত্তর সঠিক নয়।
লার্নের মারকুইস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.