2010-01-24 8 views
13

मैं एक तृतीय पक्ष जेपीईजी/EXIF ​​मैनिपुलेशन लाइब्रेरी (Mediautil) के साथ काम कर रहा हूं जो मुझे कुछ सिरदर्द पैदा कर रहा है। मैं एक छवि के EXIF ​​डेटा को बदलना चाहता हूं। ऐसा करने के लिए, मुझे अद्यतन संस्करण को अस्थायी फ़ाइल में लिखना होगा, मूल को हटाएं और फिर मूल नाम पर temp फ़ाइल का नाम बदलें। लेकिन मैं यह सब धाराओं को बंद करने के लिए सब कुछ मैं एपीआई में पा सकते हैं किया है -File.delete() को झूठा लौटने/अनजान धाराओं का पता लगाने का निदान कैसे करें?

मेरे समस्या शायद क्योंकि पुस्तकालय अभी भी यह किसी तरह से खोल दिया है कि File.delete() कॉल के विफल होने और false देता है,। इससे भी बदतर: समस्या समय-निर्भर होने लगती है, और यूनिट परीक्षण जहां कभी-कभी असफल होता है और कभी-कभी नहीं होता - लेकिन कोड बहुप्रचारित नहीं है।

विचित्र रूप से, एक पुस्तकालय कॉल है जो समस्या को हटा देता है - लेकिन यह EXIF ​​थंबनेल को भी हटा देता है, जिसे मैं वास्तव में नहीं चाहता हूं। और कोड को देखते हुए, मैं बिल्कुल नहीं देख सकता कि यह किसी भी धारा को बंद करता है जो अन्यथा खुला रहता है।

कोई भी विचार इस समस्या पर हमला कैसे करें?

संपादित करें: यह Windows XP, जावा 6. और एक और बात पर है: मुझे पता चला है कि अगर मैं File.delete() कॉल करने से पहले System.gc() कहते हैं, यह काम करता है - शायद क्योंकि है कि कुछ finalizer से चलाता है। तो यह निश्चित रूप से एक संलग्न धारा प्रतीत होता है।

+2

आपको किसी एंटीवायरस मशीन पर चल रहा है? कभी-कभी एवी आपके द्वारा लिखे जाने के बाद फ़ाइल को अस्थायी रूप से खोल सकता है, जिसके कारण आप स्पोरैडिक व्यवहार का उल्लेख करते हैं, जहां आप कभी भी "दुर्भाग्यपूर्ण" होते हैं, जब आप इसे हटाने का प्रयास करते हैं। –

+0

किस मंच पर? –

+0

@Neil अच्छा विचार है, लेकिन एवी बंद करने से कोई फर्क नहीं पड़ता। –

उत्तर

5

मैं यहां डीबगर के साथ कुछ मदद के लिए जाऊंगा। java.io सामग्री के माध्यम से एक त्वरित खुदाई से पता चलता है कि केवल finalize() उम्मीदवार FileOutputStream में है। तो वहां एक ब्रेकपॉइंट थप्पड़ मारो, अपना प्रोग्राम चलाएं, और अपनी स्ट्रीम को रिलीज़ करने के लिए FileOutputStream.finalize() को ट्रिगर करने के लिए System.gc() प्राप्त करें और प्राप्त करें। इससे आपको जवाब मिलना चाहिए कि यह आपकी समस्या है या नहीं।

एक बार जब आप इसे पुन: उत्पन्न कर सकते हैं, तो आपको उनके अंतिमकरण के साथ FileOutputStream उदाहरणों के मिलान की तत्कालता शुरू करने की आवश्यकता है। एक अच्छा डीबगर आपको प्रत्येक ऑब्जेक्ट के लिए आंतरिक जेवीएम ऑब्जेक्ट आइडेंटिफायर देगा, इसलिए यदि आप ओआईडी को ट्रैक करते समय ट्रैक कर सकते हैं, और उन्हें अंतिम रूप देने के रूप में ट्रैक कर सकते हैं, तो उम्मीद है कि आप कुंजी कॉल को finalize से संबद्ध कर पाएंगे विशिष्ट कॉल नया new FileOutputStream

एक लंबा स्लोग हो सकता है, हालांकि, यह निर्भर करता है कि आपका आवेदन कितना जटिल है।

+0

इसे अभी आज़माएं। कष्टप्रद बात यह है कि मुझे पूरा यकीन है कि अपराधी एक फ़ाइल इनपुट स्ट्रीम है, और कक्षाओं को लोड करने के लिए जेवीएम द्वारा उपयोग किया जाता है ... –

+0

ठीक है, अब मुझे इस विधि का उपयोग कर लाइब्रेरी में रिसाव मिला है। –

0

लाइब्रेरी को खोलने से पहले आप फ़ाइल का नाम क्यों नहीं बदलते? फिर नामित फ़ाइल को हटाने के लिए शायद जावा की File.deleteOnExit() का उपयोग करें। उदाहरण के लिए:

File jpeg = new File("image.jpg"); 
File temp = new File(jpeg + ".temp.jpg"); 
jpg.renameTo(temp); 
SomeObj result = exifLibrary(temp); // or exifLibrary(new FileInputStream(temp); 
OutputStream jpegStream = new FileOutputStream(jpeg); 
output.write(result.bytes(); 
output.close(); 
temp.deleteOnExit(); 
temp.delete(); 
+0

समस्या यह है कि पढ़ने वाली सभी फ़ाइलों को EXIF ​​डेटा अपडेट करने की आवश्यकता नहीं है। –

0

और कोड को देखते हुए, मैं बिल्कुल नहीं देख सकते हैं, जहां यह किसी भी धाराओं है कि अन्यथा खुला रह सकता है बंद कर देता है।

मुझे लगता है कि आप वास्तविक समस्या की पहचान कर सकते थे; यानी कि आप जिस एपीआई का उपयोग कर रहे हैं वह डिज़ाइन द्वारा खुले फ़ाइल हैंडल का उपयोग कर रहा है।

चूंकि यह एक ओपन सोर्स लाइब्रेरी है जिसका उपयोग आप स्रोत कोड एक्सेस कर रहे हैं। इसलिए, आप इसकी पुष्टि करने में सक्षम होना चाहिए, और यदि आवश्यक हो तो इसे अपने लिए ठीक करें। और एक अच्छा नागरिक बनने के लिए, एक पैच सबमिट करके परियोजना में अपना फिक्स वापस योगदान दें।

+0

मैं पहले ही लाइब्रेरी के स्रोत कोड को देखने के बारे में बात कर रहा था, एपीआई नहीं। और परेशान बात यह है कि एक लाइब्रेरी कॉल समस्या को ठीक करने के लिए प्रतीत होता है (एक साइड इफेक्ट के रूप में), लेकिन मैं नहीं देख सकता कि यह किसी भी स्ट्रीम को बंद कर रहा है। फिर फिर, यह केवल एक जीसी ट्रिगर कर सकता है जो फाइनललाइज़र चलाता है ... –

+0

"फिर फिर, यह केवल एक जीसी ट्रिगर कर सकता है जो फाइनलाइजर्स चलाता है ..." - यह मेरा सिद्धांत भी था। लेकिन यह देखने के लिए कुछ है कि क्या यह मामला है: अपने आवेदन को एक बड़े ढेर के साथ चलाएं ताकि जीसी ढेर थकावट से ट्रिगर होने की संभावना न हो। –

+0

चूंकि आपको रिसाव मिल गया है, मेरी आखिरी टिप्पणी अनावश्यक है। लेकिन अगर आपको रिसाव नहीं मिला, तो इससे मदद मिली होगी ... इसलिए मैं इसे जन्म के लिए छोड़ दूंगा। –

1

यदि आप FileOutputStream का उपयोग कर रहे हैं, तो इसे बंद करने से स्पष्ट रूप से फ़ाइल को हटाने की अनुमति मिलती है।

उदा। के बजाय:

File myFile = new File("test.txt"); 
myCustomStreamProcess(new FileOutputStream(myFile)); 
boolean test = myFile.delete(); //May return false 

आपको क्या करना चाहिए:

File myFile = new File("test.txt"); 
FileOutputStream fos = new FileOutputStream(myFile); 
myCustomStreamProcess(fos); 
fos.close(); //Allow the document to be deleted afterwards 
boolean test = myFile.delete(); //Should always return true 
+1

स्टैक ओवरफ़्लो में आपका स्वागत है। जवाब देने से पहले, आपको सावधानीपूर्वक प्रश्न और मौजूदा उत्तरों को पढ़ना चाहिए और सुनिश्चित करना चाहिए कि आप उन्हें समझें। आपका उत्तर सहायक नहीं है क्योंकि यह मानता है कि मैं उस कोड को लिख रहा हूं जो FileOutputStream का उपयोग करता है; जैसा कि सवाल में कहा गया है, वह मामला नहीं था। –

+0

आपकी टिप्पणी के लिए धन्यवाद, आपके प्रश्न ने मुझे यह कारण खोजने में मदद की कि कुछ अस्थायी परीक्षण फ़ाइलों को हटाया नहीं जा रहा था लेकिन दुर्भाग्यवश इसे अभी तक वोट नहीं दे सका। मैंने उम्मीद में उत्तर दिया कि यह दूसरों के लिए बंपिंग के लिए उपयोगी होगा, अगर मैं अनुपयुक्त हूं तो इसे हटा सकता हूं। – nkatsar

संबंधित मुद्दे