ইনপুট স্ট্রিম হিসাবে কোনও ফাইল লোড করার বিভিন্ন উপায়


216

এর মধ্যে পার্থক্য কী:

InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName)

এবং

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)

এবং

InputStream is = this.getClass().getResourceAsStream(fileName)

অন্যদের তুলনায় একে অপরকে ব্যবহার করার জন্য কখন উপযুক্ত?

আমি যে ফাইলটি পড়তে চাইছি তা ক্লাসপাথে আমার ক্লাস হিসাবে ফাইলটি পড়ে। আমার ক্লাস এবং ফাইলটি একই জারে রয়েছে এবং একটি EAR ফাইলে প্যাকেজড রয়েছে এবং ওয়েবস্পিয়ার .1.১ এ স্থাপন করা হয়েছে।

উত্তর:


289

আপনি যেভাবে fileNameপার করছেন তা কীভাবে ব্যাখ্যা করা যায় তা সম্পর্কে সূক্ষ্ম পার্থক্য রয়েছে। মূলত, আপনার কাছে দুটি পৃথক পদ্ধতি রয়েছে: ClassLoader.getResourceAsStream()এবং Class.getResourceAsStream()। এই দুটি পদ্ধতি রিসোর্সটিকে আলাদাভাবে সনাক্ত করবে।

ইন Class.getResourceAsStream(path), পাথটিকে আপনি যে শ্রেণীর কাছ থেকে কল করছেন তার প্যাকেজের স্থানীয় পথ হিসাবে ব্যাখ্যা করা হয়েছে। উদাহরণস্বরূপ কলিং জন্য, String.getResourceAsStream("myfile.txt")নিম্নলিখিত অবস্থানে আপনার ক্লাসপাথ মাধ্যমে কোনো ফাইল দেখতে হবে: "java/lang/myfile.txt"। যদি আপনার পথটি একটি দিয়ে শুরু হয় /, তবে এটি একটি পরম পথ হিসাবে বিবেচিত হবে এবং শ্রেণিপথের মূল থেকে অনুসন্ধান শুরু করবে। সুতরাং কলিংটি String.getResourceAsStream("/myfile.txt")আপনার শ্রেণীর পথে নিম্নলিখিত অবস্থানটি দেখবে ./myfile.txt

ClassLoader.getResourceAsStream(path)সমস্ত পাথকে পরম পথ হিসাবে বিবেচনা করবে। তাই কলিং String.getClassLoader().getResourceAsStream("myfile.txt")এবং String.getClassLoader().getResourceAsStream("/myfile.txt")নিম্নলিখিত অবস্থানে আপনার ক্লাসপাথ একটি ফাইল জন্য উভয় বর্ণন: ./myfile.txt

যতবার আমি এই পোস্টে কোনও অবস্থান উল্লেখ করি, এটি আপনার ফাইল সিস্টেমে নিজেই বা সংশ্লিষ্ট জার ফাইলের ভিতরে অবস্থিত হতে পারে, আপনি যে শ্রেণীর এবং / অথবা ClassLoader থেকে উত্সটি লোড করছেন তার উপর নির্ভর করে।

আপনার ক্ষেত্রে, আপনি একটি অ্যাপ্লিকেশন সার্ভার থেকে ক্লাসটি লোড করছেন, সুতরাং আপনার Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)পরিবর্তে ব্যবহার করা উচিত this.getClass().getClassLoader().getResourceAsStream(fileName)this.getClass().getResourceAsStream()কাজ করবে।

নির্দিষ্ট সমস্যা সম্পর্কে আরও বিস্তারিত তথ্যের জন্য এই নিবন্ধটি পড়ুন ।


টমক্যাট 7 এবং নীচের ব্যবহারকারীদের জন্য সতর্কতা

এই প্রশ্নের উত্তরের একটিতে বলা হয়েছে যে টমক্যাট for এর জন্য আমার ব্যাখ্যাটি ভুল বলে মনে হচ্ছে why আমি কেন আশেপাশে দেখার চেষ্টা করেছি that

সুতরাং আমি টমক্যাট এর সোর্স কোডটি টমকেটের WebAppClassLoaderবিভিন্ন সংস্করণের জন্য দেখেছি। বাস্তবায়ন findResource(String name)(যা অনুরোধকৃত রিসোর্চ করতে URL উৎপাদন জন্য utimately দায়ী) হুল বিড়াল 6 এবং হুল বিড়াল 7 কার্যত অভিন্ন, কিন্তু হুল বিড়াল 8 ভিন্ন।

সংস্করণ 6 এবং In এ, বাস্তবায়ন সংস্থানটির নামটি স্বাভাবিক করার চেষ্টা করে না। এর অর্থ এই যে এই সংস্করণগুলিতে ইভেন্টের classLoader.getResourceAsStream("/resource.txt")মতো একই ফলাফল নাও আসতে পারে classLoader.getResourceAsStream("resource.txt")(যেহেতু জাভাদোক নির্দিষ্ট করে)। [সোর্স কোড]

ভার্সন ৮-এ যদিও, এই সংস্থার গ্যারান্টির জন্য রিসোর্সের নামটি স্বাভাবিক করা হয়েছে যে ব্যবহৃত হওয়া সংস্থার নামের পরম সংস্করণ is সুতরাং, টমক্যাট 8-এ, উপরে বর্ণিত দুটি কলের সর্বদা একই ফলাফলটি ফিরে আসা উচিত। [সোর্স কোড]

ফলস্বরূপ, আপনি ব্যবহার করছেন অতিরিক্ত সতর্ক হতে হবে ClassLoader.getResourceAsStream()বা Class.getResourceAsStream()তার আগে হুল বিড়াল সংস্করণের উপর 8. চেয়ে আর তুমি যে মনে রাখা উচিত নয় class.getResourceAsStream("/resource.txt")আসলে কল classLoader.getResourceAsStream("resource.txt")(নেতৃস্থানীয় /ছিনতাই করা হয়)।


2
আমি পুরোপুরি নিশ্চিত যে এর getClass().getResourceAsStream("/myfile.txt")থেকে আলাদা আচরণ করে getClassLoader().getResourceAsStream("/myfile.txt")
ব্রায়ান গর্ডন

@ ব্রায়ান গর্ডন: তারা আলাদা আচরণ করে না। প্রকৃতপক্ষে, Class.getResourceAsStream (স্ট্রিং) এর জাভাদোক নীচের জিনিসটি বলেছেন: "এই পদ্ধতিটি এই বস্তুর শ্রেণি লোডারকে প্রতিনিধিত্ব করে" " classloader।
লর্ডঅফ দ্য পিগস

প্রকৃত উত্স দেখুন Class.getResourceAsStream অগ্রণী ফরোয়ার্ড স্ল্যাশকে সরিয়ে দেয় যদি আপনি একটি চূড়ান্ত পথ সরবরাহ করেন।
ব্রায়ান গর্ডন

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

আমি খুঁজে পাইনি getClassLoader()এর String, এটি একটি ভুল বা একটি এক্সটেনশন প্রয়োজন?
এএএ

21

MyClass.class.getClassLoader().getResourceAsStream(path)আপনার কোডের সাথে যুক্ত রিসোর্স লোড করতে ব্যবহার করুন । MyClass.class.getResourceAsStream(path)একটি শর্টকাট হিসাবে ব্যবহার করুন , এবং আপনার শ্রেণীর প্যাকেজ মধ্যে প্যাকেজ সংস্থান জন্য।

Thread.currentThread().getContextClassLoader().getResourceAsStream(path)সংস্থানগুলি ক্লায়েন্ট কোডের অঙ্গ হিসাবে প্রাপ্ত করার জন্য, কলিং কোডটির সাথে দৃly়ভাবে আবদ্ধ নয় Use থ্রেড প্রসঙ্গ শ্রেনী লোডার যে কোনও কিছুতে ইশারা করতে পারে তাই আপনার এটিকে যত্নবান হওয়া উচিত।


6

সমতল পুরাতন জাভা 7 এ সরল পুরাতন জাভা এবং অন্য কোনও নির্ভরতা পার্থক্য প্রদর্শন করে না ...

আমি করা file.txtমধ্যে c:\temp\আমি করা c:\temp\ক্লাসপাথ উপর।

দুটি কলের মধ্যে একটি মাত্র পার্থক্য রয়েছে।

class J {

 public static void main(String[] a) {
    // as "absolute"

    // ok   
    System.err.println(J.class.getResourceAsStream("/file.txt") != null); 

    // pop            
    System.err.println(J.class.getClassLoader().getResourceAsStream("/file.txt") != null); 

    // as relative

    // ok
    System.err.println(J.class.getResourceAsStream("./file.txt") != null); 

    // ok
    System.err.println(J.class.getClassLoader().getResourceAsStream("./file.txt") != null); 

    // no path

    // ok
    System.err.println(J.class.getResourceAsStream("file.txt") != null); 

   // ok
   System.err.println(J.class.getClassLoader().getResourceAsStream("file.txt") != null); 
  }
}

অনেক ধন্যবাদ, আমার জন্য কেবল 'J.class.getResourceAsStream ("file.txt")' কাজ করেছেন
আব্বাসালিম

3

এই সব উত্তর কাছাকাছি, পাশাপাশি উত্তর এই প্রশ্ন , যে সুপারিশ লোড পরম URL গুলি, "/foo/bar.properties" চিকিত্সা একই মত 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)অতীতে ব্যবহার করেছি এবং কোনও সমস্যা হয়নি।

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


সম্ভবত টমক্যাট স্পেসিফিকেশনটিকে সম্মান না করার সিদ্ধান্ত নিয়েছে এবং, এবং সমস্ত পথকে ClassLoader.getResourceAsStream()পরম হিসাবে বিবেচনা করে না ? এটি প্রশংসনীয় কারণ কারণ উপরে কিছু মন্তব্যে উল্লিখিত হয়েছে, Class.getResourceAsStreamআসলে getClassLoader () কে getResourceAsStream` কল করে তবে কোনও অগ্রণী স্ল্যাশ স্ট্রিপ করে।
লর্ডঅফ দ্য পিগস

জাভা এসই এর উত্স কোডটি যাচাই করার পরে, আমি মনে করি আমি উত্তরটি ধারণ করেছি: উভয় Class.getResourceAsStream()এবং ClassLoader.getResourceAsStream()শেষ পর্যন্ত ClassLoader.findResource()কলিংটি শেষ হয় যা একটি সুরক্ষিত পদ্ধতি যার ডিফল্ট বাস্তবায়ন খালি, তবে যার জাভাদোক স্পষ্টভাবে বলে "শ্রেণি লোডার বাস্তবায়নগুলি কোথায় নির্দিষ্ট করতে এই পদ্ধতিটি ওভাররাইড করা উচিত? সংস্থান খুঁজে পেতে "। আমি সন্দেহ করি যে টমক্যাটের এই নির্দিষ্ট পদ্ধতির প্রয়োগটি ত্রুটিযুক্ত হতে পারে।
লর্ডঅফ দ্য পিগস

আমিও বাস্তবায়ন তুলনায় থাকেন WebAppClassLoader.findResource(String name)মধ্যে হুল বিড়াল 7 এর সাথে হুল বিড়াল 8 , এবং এটি মনে হচ্ছে, একটি কী পার্থক্য আছে। টমক্যাট 8 স্পষ্টভাবে একটি লিডিং যুক্ত করে সংস্থার নামটিকে স্পষ্টতই স্বাভাবিক করে /তোলে যাতে এতে কোনও নাম থাকে না, যা সমস্ত নামকে পরম করে তোলে। টমকেট 7 করে না। টমক্যাট 7
লর্ডঅফ দ্য পিগস

আমি আমার উত্তরে সে সম্পর্কে একটি অনুচ্ছেদ যুক্ত করেছি।
লর্ডঅফ দ্য পিগস 0

0

কোনও সাফল্য ছাড়াই ফাইলটি লোড করার জন্য কিছু উপায়ে চেষ্টা করার পরে, আমি মনে করি আমি ব্যবহার করতে পারি FileInputStream, যা নিখুঁতভাবে কাজ করেছিল।

InputStream is = new FileInputStream("file.txt");

এটি একটিতে একটি ফাইল পড়ার অন্য উপায় InputStream, এটি বর্তমানে চলমান ফোল্ডার থেকে ফাইলটি পড়ে।


এটি কোনও ফাইল নয়, এটি একটি উত্স। উত্তর সঠিক নয়।
লার্নের মারকুইস

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

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