getResourceAsStream () বনাম ফাইলআইপুট স্ট্রিম


173

আমি একটি ওয়েব অ্যাপে একটি ফাইল লোড করার চেষ্টা করছিলাম এবং আমি FileNotFoundযখন ব্যবহার করতাম তখন ব্যতিক্রম হচ্ছিলাম FileInputStream। যাইহোক, একই পথটি ব্যবহার করে আমি ফাইলটি লোড করতে সক্ষম হয়েছি getResourceAsStream()। দুটি পদ্ধতির মধ্যে পার্থক্য কী এবং কেন একটি কাজ করে অন্যটি না করে?

উত্তর:


256

java.io.Fileএবং স্ত্রীদেরকে স্থানীয় ডিস্কে ফাইল সিস্টেমে কাজ করে। আপনার সমস্যার মূল কারণ হ'ল আপেক্ষিক পাথগুলি java.ioবর্তমান ওয়ার্কিং ডিরেক্টরিের উপর নির্ভরশীল। অর্থাৎ যে ডিরেক্টরি থেকে জেভিএম (আপনার ক্ষেত্রে: ওয়েবসারকের একটি) শুরু হয়েছে। এই উদাহরণস্বরূপ হতে পারে C:\Tomcat\binবা কিছু সম্পূর্ণরূপে ভিন্ন, কিন্তু এইভাবে না C:\Tomcat\webapps\contextname বা যাই হোক না কেন আপনি এটা বলে আশা করা চাই। একটি সাধারণগ্রহণ প্রকল্পে, এটি হবে C:\Eclipse\workspace\projectname। আপনি বর্তমান ওয়ার্কিং ডিরেক্টরিটি নিম্নলিখিত পদ্ধতিতে শিখতে পারেন:

System.out.println(new File(".").getAbsolutePath());

তবে, ওয়ার্কিং ডিরেক্টরি কোনওভাবেই প্রোগ্রামিকভাবে নিয়ন্ত্রণযোগ্য নয়। আপনার সত্যিকারের আপেক্ষিক পাথের পরিবর্তে API এ পরম পাথগুলি ব্যবহার করা পছন্দ করা উচিত Fileprefer যেমনC:\full\path\to\file.ext

আপনি জাভা (ওয়েব) অ্যাপ্লিকেশনগুলিতে হার্ডকোড বা পরম পাথ অনুমান করতে চান না। এটি কেবল পোর্টেবিলিটি সমস্যা (যেমন এটি সিস্টেম এক্সে চলে, তবে সিস্টেম ওয়াই তে নয়)। সাধারণ অনুশীলন হ'ল এই ধরণের সংস্থানগুলি ক্লাসপথে রাখুন , বা শ্রেণিপথের সাথে তার সম্পূর্ণ পথ যুক্ত করা (একক্লিপের মতো আইডিইতে যেটি srcফোল্ডার এবং যথাক্রমে "বিল্ড পাথ" থাকে)। এইভাবে আপনি ClassLoaderদ্বারা ClassLoader#getResource()বা এর সাহায্যে তাদের দখল করতে পারেন ClassLoader#getResourceAsStream()। এটি আপনার ক্লাসপ্যাথের "মূল" এর সাথে সম্পর্কিত ফাইলগুলি সনাক্ত করতে সক্ষম, যেমনটি আপনি কাকতালীয়ভাবে আবিষ্কার করেছিলেন। ওয়েব অ্যাপ্লিকেশনগুলিতে (বা অন্য কোনও অ্যাপ্লিকেশন যা একাধিক ক্লাসলোডার ব্যবহার করে) এতে এটির জন্য ClassLoaderপ্রত্যাবর্তিত হিসাবে ব্যবহার করার পরামর্শ দেওয়া হয় Thread.currentThread().getContextClassLoader()যাতে আপনি ওয়েবঅ্যাপের প্রসঙ্গটিও "বাইরে" দেখতে পারেন।

ওয়েব অ্যাপসে অন্য বিকল্প হ'ল ServletContext#getResource()এবং এর সমকক্ষ ServletContext#getResourceAsStream()। এটি webফোল্ডার সহ ওয়েব অ্যাপ্লিকেশন প্রকল্পের সর্বজনীন ফোল্ডারে থাকা ফাইলগুলিতে অ্যাক্সেস করতে সক্ষম /WEB-INFServletContextউত্তরাধিকারসূত্রে দ্বারা সার্ভলেট পাওয়া যায়getServletContext() পদ্ধতি, আপনি কল করতে পারেন এটা হিসাবে হয়।

আরো দেখুন:


5
@khylo: সম্পর্কিত: stackoverflow.com/questions/7952090/...
BalusC

27

getResourceAsStream ওয়েব অ্যাপ্লিকেশনগুলির জন্য এটি করার সঠিক উপায় (যেমন আপনি ইতিমধ্যে শিখেছেন)।

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


3
+1 - যদিও "কাজ করতে পারে না" খুব শক্ত। (ফাইল সিস্টেম থেকে পড়া কাজ করার জন্য তৈরি করা যেতে পারে, তবে এটি বহনযোগ্যভাবে করা একটি কৌশল ... এবং আরও অনেক কোড, বিশেষত যদি উত্সটি একটি জেআর তে থাকে))
স্টিফেন সি

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

@ স্টেফেন - আমি মনে করি না "কাজ করতে পারে না" খুব শক্তিশালী। এমনকি অ্যাপ সার্ভারে বিভিন্ন পাথ সহ দুটি পৃথক সার্ভারে স্থাপনের মতো সাধারণ কিছু এটি ভেঙে দেবে। মুল বক্তব্যটি হ'ল আপনার WAR কে যতটা সম্ভব স্বয়ংসম্পূর্ণ করা দরকার। আপনার বক্তব্যটি সঠিক, তবে আমি আমার কথার সাথে লেগে যাচ্ছি।
duffymo

14

ফাইলআইপুট স্ট্রিম জাভা প্রক্রিয়াটির কার্যকরী ডিরেক্টরি থেকে আপেক্ষিক হিসাবে আপনি কনস্ট্রাক্টরের কাছে যে ফাইল পাস করবেন সেটি লোড করবে । সাধারণত একটি ওয়েব পাত্রে, এটি এর মতো কিছুbin ফোল্ডারের ।

getResourceAsStream()আপনার অ্যাপ্লিকেশনটির ক্লাসপথ থেকে কোনও ফাইল পাথ আপেক্ষিকভাবে লোড করবে ।


12

FileInputStreamবর্গ অন্তর্নিহিত ফাইল সিস্টেম সাথে সরাসরি কাজ করে। যদি প্রশ্নে থাকা ফাইলটি শারীরিকভাবে সেখানে উপস্থিত না হয়, তবে এটি খুলতে ব্যর্থ হবে। getResourceAsStream()পদ্ধতি ভিন্নভাবে কাজ করে। এটি ClassLoaderযে ক্লাসটি বলা হয় তার ব্যবহার করে রিসোর্সটি সনাক্ত এবং লোড করার চেষ্টা করে। এটি এটি সন্ধান করে, উদাহরণস্বরূপ, jarফাইলগুলিতে এম্বেড হওয়া সংস্থানগুলি ।


ঠিক আছে, একটি জারের মধ্যে থাকা ফাইলগুলি এখনও একটি ফাইল সিস্টেমে শারীরিকভাবে "উপস্থিত" থাকে যা কেবলমাত্র অন্যান্য ফাইলের মধ্যে থাকে
ম্যাট বি

1
আচ্ছা, হ্যাঁ, অবশ্যই তবে এগুলি সাধারণত ফাইল সিস্টেমে স্বতন্ত্র সত্তা হিসাবে দেখা যায় না, যদি না আপনি আবেদনটি jarফাইল ফর্ম্যাট এবং এর প্রভাবগুলি সম্পর্কে জানেন । এবং জাভাতে, উপযুক্তদের ClassLoaderএই জ্ঞান থাকতে পারে, তবে একটি সমভূমি FileInputStreamঅবশ্যই নেই।
শিখ

7

classname.getResourceAsStream () ক্লাসনামের ক্লাসলোডারের মাধ্যমে কোনও ফাইল লোড করে। যদি ক্লাসটি কোনও জার ফাইল থেকে আসে তবে সেখান থেকে সংস্থানটি লোড হবে।

ফাইলআইপুট স্ট্রিম ফাইল সিস্টেম থেকে একটি ফাইল পড়তে ব্যবহৃত হয়।


0

ফাইল রিড (java.io) এবং রিসোর্স রিড (ClassLoader.getResourceAsStream ()) হিসাবে চিহ্নিত করে উভয় ব্যবহারকে পৃথক করে আমি এখানে আছি।

ফাইল পড়ুন - ১. স্থানীয় ফাইল সিস্টেমে কাজ করে। ২. বর্তমান জেভিএম চালু হওয়া ডিরেক্টরি থেকে অনুরোধ করা ফাইলটি রুট হিসাবে চিহ্নিত করার চেষ্টা করে 3.., / দেব / ফাইল বা সি: \ ডেটার মতো প্রাক-নির্ধারিত স্থানে প্রসেসিংয়ের জন্য ফাইলগুলি ব্যবহার করার সময় আদর্শভাবে ভাল।

রিসোর্স পঠন - 1. শ্রেণীর পথে কাজ করে 2. বর্তমান বা পিতামাতার ক্লাসলোডার শ্রেণিপথের মধ্যে ফাইল / সংস্থান সনাক্ত করার চেষ্টা করে। ৩. যুদ্ধ বা জারের মতো প্যাকেজযুক্ত ফাইলগুলি থেকে ফাইলগুলি লোড করার চেষ্টা করার সময় আদর্শভাবে ভাল।

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