मुझे दो तरीकों से कुछ परेशानी हो रही है जो मैं लिखने की कोशिश कर रहा हूं। दोनों में फ़ाइल में पढ़ने के लिए स्कैनर का उपयोग करना शामिल है, जहां प्रत्येक पंक्ति अल्पविराम सीमित है। विधियां मेरी फाइलियो कक्षा का हिस्सा हैं। उस वर्ग के अलावा, मेरे पास दो अन्य वर्ग भी हैं, खाद्य और खाद्यअरेसूची। खाद्य वस्तुओं में खाद्य दान से जानकारी के कई टुकड़े होते हैं (जिन्होंने वस्तुओं का दान किया, दान का कारण इत्यादि)। FoodArrayList क्लास में एरेलेलिस्ट के रूप में बहुत अधिक कार्यक्षमता है, सिवाय इसके कि मैंने इसे पूरी तरह से खाद्य वस्तुओं को संग्रहीत करने के उद्देश्य से बनाया है।स्कैनर बंद होने पर कैसे जांचें
दो तरीकों मैं के साथ संघर्ष कर रहा हूँ इस प्रकार हैं:
- फ़ाइल में पढ़ता है और केवल फ़ाइल की पंक्तियों की संख्या की गणना। यह लाइनों की संख्या देता है। इस विधि का उपयोग FoodArrayList के आकार को निर्धारित करने के लिए किया जाता है। ऐसा इसलिए है क्योंकि फ़ाइल की प्रत्येक पंक्ति एक खाद्य वस्तु का वर्णन करती है।
- फ़ाइल में पढ़ता है और जानकारी को FoodArrayList ऑब्जेक्ट में संग्रहीत करता है। याद रखें कि प्रत्येक कॉमा-सीमांकित रेखा एक खाद्य वस्तु का वर्णन करती है। इसलिए, यह विधि फ़ाइल के माध्यम से जाती है, खाद्य वस्तुओं को बनाती है, और उन्हें फ़ाइल के अंत तक पहुंचने तक उन्हें FoodArrayList में डाल देती है।
मैं किसके साथ संघर्ष कर रहा हूं यह है कि मैं दोनों तरीकों से अपना स्कैनर बंद करता हूं। और मैं स्कैनर बंद होने पर यह पता लगाने के लिए if
कथन लिखने के तरीके से संघर्ष कर रहा हूं। दोनों विधियों में, मेरे पास विधि की शुरुआत में निम्नलिखित है:
try{
if(scan.hasNext() == false || scan == null)
scan = new Scanner(new File(this.getFileName()));
}
catch(FileNotFoundException fnfe){
System.err.println("The " + fileName + " could not be found.");
}
catch(IOException ioe){
ioe.printStackTrace();
}
हालांकि यह काम नहीं करता है। यदि मैं पहले विधि # 1 का उपयोग करता हूं और बाद में विधि # 2 का उपयोग करने की कोशिश करता हूं (याद रखें कि मैं प्रत्येक विधि के अंत में स्कैनर बंद करता हूं), if
कथन छोड़ दिया गया है और scan
कभी भी पुनर्स्थापित नहीं किया गया है और मुझे IllegalStateException
फेंक दिया गया है।
एक बहुत बड़ा मुद्दा जिसे मैंने पहले उल्लेख किया था, यह है: मैं दोनों विधियों को पुन: प्रयोज्य बनाना चाहता हूं। यदि विधि # 1 फ़ाइल के अंत तक चलता है और बाद में मैं उपयोग विधि # 2 पर जाता हूं, तो मैं स्कैनर ऑब्जेक्ट को फिर से फ़ाइल की शुरुआत से पढ़ना चाहता हूं। और ऐसा लगता है कि ऐसा करने का एकमात्र तरीका स्कैनर ऑब्जेक्ट को पुनर्स्थापित करना है।
जब मैंने पहली बार जावा में आई/ओ के बारे में सीखा, तो मुझे याद है कि हमेशा स्कैनर ऑब्जेक्ट्स को बंद करते समय सुनिश्चित करें कि आप उनका उपयोग कर रहे हैं। यह ऐसा कुछ है जो लगभग मेरे दिमाग में शामिल हो गया है। भले ही, मैं इसके आसपास कैसे हो सकता हूं? एक विचार मैंने अपने दोनों तरीकों के अंत में scan
को शून्य करने के लिए सेट किया था। क्या यह भी जरूरी है? मैंने स्टैक ओवरफ्लो में अन्य पोस्टों पर पढ़ा है जो मुझे मेरे स्कैनर ऑब्जेक्ट को बंद करने के लिए प्रेरित नहीं करेंगे और कचरा कलेक्टर को इसकी देखभाल करने दें।
इस सब के अलावा, मैं यह भी सोच रहा था कि एक बार बंद होने के बाद स्कैनर के साथ वास्तव में क्या होता है और इसे फिर से खोल नहीं किया जा सकता है। मैं समझता हूं कि स्ट्रीम के साथ इसका कुछ संबंध है, लेकिन मुझे बिल्कुल पता नहीं है कि वे जावा के संदर्भ में क्या हैं। मैंने Stream class को देखने का प्रयास किया, लेकिन इससे अधिक समझ प्राप्त करने में सक्षम नहीं था।
यहाँ मेरी विधियों में से दोनों से कोड है:
विधि # 1
public int numberOfLines(){
try{
if(scan.hasNext() == false || scan == null)
scan = new Scanner(new File(this.getFileName()));
}
catch(FileNotFoundException fnfe){
System.err.println("The " + fileName + " could not be found.");
}
catch(IOException ioe){
ioe.printStackTrace();
}
int lineCount = 0;
while(scan.hasNextLine()){
scan.nextLine();
lineCount++;
}
scan.close();
return lineCount;
}
विधि # 2
public void readFile(FoodArrayList fal){
try{
if(scan.hasNext() == false || scan == null)
scan = new Scanner(new File(this.getFileName()));
}
catch(FileNotFoundException fnfe){
System.err.println("The " + fileName + " could not be found.");
}
catch(IOException ioe){
ioe.printStackTrace();
}
while(scan.hasNextLine()){
String stringRead = scan.nextLine();
StringTokenizer tokens = new StringTokenizer(stringRead,",");
Food temp = new Food();
temp.setCorpName(tokens.nextToken());
temp.getContact().setLast(tokens.nextToken());
temp.getContact().setFirst(tokens.nextToken());
temp.setDate(tokens.nextToken());
temp.setProductCode(tokens.nextToken());
temp.setDescription(tokens.nextToken());
temp.setReason(tokens.nextToken());
String numberString = tokens.nextToken();
int number = Integer.parseInt(numberString);
temp.setNumber(number);
temp.setCoP(tokens.nextToken());
fal.insert((Food)temp);
}
scan.close();
}
मैं इन दोनों रखना चाहते हैं तरीके अलग हैं।
FoodArrayList list;
FileIO fio = new FileIO();
int listSize = fio.numberOfLines();
list = new FoodArrayList(listSize);
fio.readFile(list);
मेरी FileIO वर्ग के डिफ़ॉल्ट निर्माता पहले से ही विशेष फ़ाइल मैं पढ़ने का प्रयास कर रहा हूँ पर विचार करता है: यह इसलिए है क्योंकि मेरे मुवक्किल कक्षा में, मैं निम्नलिखित प्रदर्शन कर रहा हूं। बेशक, ओवरलोडेड कन्स्ट्रक्टर एक इनपुट के रूप में एक अलग फ़ाइल नाम का उपयोग करने की अनुमति देता है। इस मुद्दे पर किसी प्रकार की मदद की सराहना की जाएगी।
'if (scan.hasNext() == false || scan == null) 'आपको शर्तों को स्वैप करना चाहिए, क्योंकि यदि' स्कैन 'ऑब्जेक्ट' शून्य 'होने की संभावना है तो आपको इसे पहले देखना चाहिए। इसके अलावा आपको केवल पहली विधि की आवश्यकता है यदि आप सरणी में 'खाद्य' ऑब्जेक्ट्स संग्रहीत कर रहे हैं। लेकिन मुझे लगता है कि आप पहले से ही कुछ संग्रह का उपयोग कर रहे हैं, आवश्यक लाइन गिनती नहीं। – YoungHobbit
FoodArrayList सूची क्या है? जब आप अपने कन्स्ट्रक्टर को कॉल करते हैं और एक तर्क के रूप में सूचीबद्ध करते हैं तो आप वास्तव में क्या करना चाहते हैं? –
FoodArrayList एक ऐसी कक्षा है जो एक ArrayList ऑब्जेक्ट के समान ही संचालित होती है, सिवाय इसके कि इसे केवल खाद्य वस्तुओं को संग्रहित करने के लिए डिज़ाइन किया गया है। मुझे पता है कि मैं सिर्फ ऐरेलिस्ट का उदाहरण इस्तेमाल कर सकता था, लेकिन मेरे पास इस विशेष वर्ग को बनाने के मेरे कारण हैं। जब मैं एक तर्क के रूप में सूची आकार को पास करता हूं, तो मैं मूल रूप से सूची आकार के आकार के साथ खाद्य वस्तुओं की एक सरणी बना रहा हूं। – coolDude