2012-09-24 34 views
6

एक सर्वलेट में, मैं एक स्ट्रिंगबिल्डर में HTML सामग्री की एक बड़ी मात्रा का निर्माण कर रहा हूं, अंत में, प्रतिक्रिया के प्रिंटवाइटर को लिखा जाना चाहिए। प्रिंटवाइटर का उपयोग करने के लिए, सामग्री को स्ट्रिंग के रूप में प्राप्त करने के लिए इसे पहले स्ट्रिंगबिल्डर के टूस्ट्रिंग() विधि को कॉल करना होगा। लेकिन यह अनावश्यक रूप से सामग्री को डुप्लिकेट करता है। क्या स्ट्रिंगबिल्डर से सीधे लिखने का कोई तरीका है क्योंकि यह पहले से ही सामग्री धारण कर रहा है?बिना स्ट्रिंग के एक स्ट्रिंगबिल्डर लिखें, (

प्रिंटवाइटर एक CharSequence स्वीकार कर सकता है, लेकिन प्रलेखन में कहा गया है कि यह CharSequence के toString() को कॉल करता है, इसलिए यह वास्तव में मदद नहीं करता है।

एकमात्र स्पष्ट तरीका मैं देख सकता हूं कि एक समय में एक चरित्र प्राप्त करने और लिखने के लिए स्ट्रिंगबिल्डर के charAt (i) विधि का उपयोग करना है, लेकिन क्या यह एक सुधार होगा?

+2

सुधार सापेक्ष है। यदि आपका लक्ष्य स्मृति खपत को कम करना है, तो हाँ यह एक सुधार होगा। यदि आप धीमे हो तो आपको परीक्षण करना चाहिए। मुझे आश्चर्य नहीं होगा अगर आउटपुट स्ट्रीम के बफरिंग के कारण - प्रदर्शन दंड इतना बड़ा नहीं था। –

उत्तर

7

एक विकल्प के रूप में, आप स्ट्रिंगबिल्डर को छोड़ सकते हैं और StringWriter और PrintWriter का उपयोग कर सकते हैं।

+0

मुझे HTML सामग्री लेने और इसे सर्वलेट के प्रिंटवाइटर को लिखने की आवश्यकता है, जिसे HttpServletResponse की getWriter() विधि को कॉल करके प्राप्त किया जाता है। मुझे स्ट्रिंगवाइटर के साथ गठबंधन करने का कोई तरीका नहीं दिख रहा है। – worpet

2

तुम सिर्फ पहली जगह में के बजाय StringBuilder को PrintWriter को लिख सकता है ...

charAt का उपयोग करना निश्चित रूप से आपकी मदद नहीं करेंगे। यह इस तरह से करने के लिए बहुत खराब प्रदर्शन पैदा करेगा। यदि आप वास्तव में उस दिशा में आगे बढ़ना चाहते हैं तो StringBuilder.subString(start,end) विधि का उपयोग कर सकते हैं। यह विधि आपको एक समय में उदाहरण के लिए 1000 वर्ण पढ़ने और प्रिंटवाइटर पर प्रिंट करने की अनुमति देगी ...

+0

'StringBuilder.substring()' प्रत्येक बार जब आप इसे कॉल करते हैं तो एक नया स्ट्रिंग आवंटित करेगा। यद्यपि आवंटित स्मृति की कुल मात्रा छोटी होगी, लेकिन यह बहुत अधिक ओवरहेड लगाएगा। मैं वास्तव में सोचता हूं कि charAt() का उपयोग करना बुरा नहीं होगा क्योंकि संभवतः सर्वलेट के प्रिंटवाइटर को बफर किया जाता है। –

2

StringBuilder कक्षा स्ट्रिंग को एक आंतरिक चार सरणी में संग्रहीत करती है। समस्या यह है कि यह चार सरणी सुलभ नहीं है।

प्रस्तावित समाधान:

1) आप ObjectOutputStream है, जहां आप writeObjectOverride(Object obj) विधि ओवरराइड का विस्तार एक नया वर्ग बना सकते हैं। फिर बस StringBuilder उदाहरण को क्रमबद्ध करें जिसमें आपने अपना HTML दस्तावेज़ बनाया है। आपकी ओवरराइड writeObjectOverride(Object obj) विधि Stringbuilder की आंतरिक चार सरणी के साथ कॉल की जाएगी जो क्रमबद्ध प्रक्रिया का हिस्सा है, और वॉयला: आपके पास स्ट्रिंग बिल्डर की आंतरिक चार सरणी का संदर्भ है, यह सब आपको Servlet's PrintWriter में लिखने के लिए है आउटपुट ... नोट: आपकी writeObjectOverride() विधि को कई बार बुलाया जाएगा, जाहिर है आप उन लोगों को अवहेलना कर सकते हैं जो आपको वांछित चार सरणी के अलावा कुछ और पास करते हैं।

2) आप कक्षा का उपयोग StringBuilder के बजाय कर सकते हैं जिसमें array() आंतरिक सरणी लौटने की विधि है। CharBuffer के रूप में कई संलग्न नहीं है (या डाल) StringBuilder के रूप में संचालन, तो यह उन एक छोटा सा (क्या आप वास्तव में जरूरत के आधार पर) का विस्तार करने की आवश्यकता होगी ...

3) आप का अपना स्वयं का कार्यान्वयन लिख सकता है StringBuilder, या इसके बजाय आप इसका क्या उपयोग करते हैं। इस तरह आपको ऑब्जेक्ट तक पहुंच होगी (उदाहरण के लिए एक चार सरणी) जिसमें आप एकत्रित पाठ को संग्रहीत करते हैं ...

+0

मुझे यकीन नहीं है कि समाधान 1 काम करेगा क्योंकि writeObjectOverride का उपयोग करने के लिए आपको अधिकांश धारावाहिक तर्क को फिर से लिखना होगा क्योंकि एक पैरामीटर ऑब्जेक्टऑटपुटस्ट्रीम कन्स्ट्रक्टर ऑब्जेक्टऑवर्राइड लिखने के लिए कॉल को अक्षम करता है। यानी यह इस तरह इस्तेमाल करने के लिए डिज़ाइन नहीं किया गया है। इसके अलावा कोई अन्य तरीका नहीं है जिसे आप सामान्य मामले को संभालने के लिए writeObjectOverride के भीतर कॉल कर सकते हैं। आप हालांकि रिफ्लेक्सन का उपयोग कर सकते हैं लेकिन सुरक्षा प्रबंधक आपके रास्ते में जा सकता है। – cquezel