2011-12-15 19 views
6

मेरे पास दो संसाधन फ़ोल्डर हैं।जावा प्रोग्रामेटिक रूप से संसाधनों/स्रोत फ़ोल्डर में फ़ाइल बनाएँ?

src - यहाँ कर रहे हैं मेरी संसाधन फ़ाइलें (छवियों, .properties) फ़ोल्डर (संकुल) में आयोजित किया - यहाँ मेरी जावा फ़ाइलों

संसाधन हैं।

क्या प्रोग्राम संसाधन में प्रोग्रामिंग रूप से एक और .properties फ़ाइल जोड़ने का कोई तरीका है?

मैं कुछ इस तरह की कोशिश की:

public static void savePropertiesToFile(Properties properties, File propertiesFile) throws IOException { 
     FileOutputStream out = new FileOutputStream(propertiesFile); 
     properties.store(out, null); 
     out.close(); 
    } 

और बनाया है कि इससे पहले कि:

new File("/folderInResources/newProperties.properties"); 

लेकिन यह फाइल सिस्टम पर है कि पथ के लिए लग रहा है। संसाधन फ़ोल्डर में देखने के लिए मैं इसे कैसे मजबूर कर सकता हूं?

संपादित करें: मुझे यह कहना है कि इसके बारे में क्या है। मेरे पास एक जीयूआई एप्लीकेशन है और मैं 2 भाषाओं का समर्थन करता हूं (2। संसाधन फ़ोल्डर में प्रॉपर्टीज फाइलें)। अब मैंने एक विकल्प जोड़ा है कि उपयोगकर्ता आसानी से एप्लिकेशन का अनुवाद कर सकता है और जब वह समाप्त होता है तो मैं उस छिपे हुए फ़ोल्डर में डिस्क पर उस नई .properties को सहेजता हूं और इसे वहां से पढ़ता हूं। लेकिन मैं उम्मीद कर रहा था कि मैं मौजूदा भाषाओं (संसाधन फ़ोल्डर) के बगल में उस नई .properties फ़ाइलों (नई भाषा) को बचा सकता हूं। मेरे पास एक स्थिर संदेश वर्ग है जो जानता है कि डिस्क से संसाधनों को लोड करने और संसाधन फ़ोल्डर में डिफ़ॉल्ट दोनों को कैसे लोड किया जाए। लेकिन यदि उपयोगकर्ता किसी अन्य मशीन पर यह .jar फ़ाइल लेता है, तो उसके पास उस नई भाषा नहीं होगी क्योंकि वे उस कंप्यूटर पर डिस्क पर हैं, अंदर नहीं .jar फ़ाइल।

उत्तर

0

संसाधन क्लास लोडर के माध्यम से लोड किए जाते हैं, और डिफ़ॉल्ट क्लास लोडर कैश भारी रूप से लोड होते हैं।

गैर-स्थैतिक फ़ाइल सिस्टम से संसाधन पढ़ने के लिए आपको अपने इच्छित वर्ग के साथ अपने स्वयं के वर्ग लोडर की आवश्यकता है।

+0

@ Thorbjørn Ravn Andersen यदि मैं इसे आजमाता हूं: 'MyClass.class.getClassLoader()' मुझे कोई भी तरीका नहीं दिख रहा है जो मुझे कुछ रास्ता देगा। – vale4674

+0

आप संसाधन नहीं लिख सकते हैं। हालांकि, आपके पास एक क्लास लोडर हो सकता है जो फ़ाइल सिस्टम से संसाधन लोड करता है। –

0

समस्या क्लासपाथ में कई रूट निर्देशिकाएं हो सकती हैं, इसलिए यह निर्दिष्ट करने के लिए कि कौन सा स्टोर स्टोर करने के लिए किसी मौजूदा फ़ाइल या निर्देशिका के बिना कठिन होगा।

यदि आपके पास मौजूदा फ़ाइल लोड है।

File existingFile = ...; 
File parentDirectory = existingFile.getParentFile(); 
new File(parentDirectory, "newProperties.properties"); 

अन्यथा निर्देशिका में एक हैंडल प्राप्त करने का प्रयास करें जो आपको पता है कि आपकी संसाधन निर्देशिका में अद्वितीय है। (यह सुनिश्चित नहीं है कि यह काम करता है)

URL url = this.getClass().getResource("/parentDirectory"); 
File parentDirectory = new File(new URI(url.toString())); 
new File(parentDirectory, "newProperties.properties"); 
+0

@ लियोनेल पोर्ट मैंने इस संयोजन की कोशिश की और यह काम नहीं करता है। \t \t 'यूआरएल यूआरएल = FilesUtil.class.getResource ("/संदेश/संदेश.प्रोपर्टीज "); \t \t System.out.println (url); \t \t फ़ाइल फ़ाइल = नई फ़ाइल (url.toURI()); \t \t System.out.println (फ़ाइल); ' पहला आउटपुट मुझे डिस्क पर पूर्ण पथ देता है लेकिन जब मैं इसे से फ़ाइल बनाने का प्रयास करता हूं, तो यह मुझे 'java.lang.IleglegalrrumentException देता है: यूआरआई में एक है प्राधिकरण घटक 'अपवाद। ऐसा लगता है जैसे जावा इसके कार्यक्षेत्र (.jar फ़ाइल) के अंदर नहीं लिख सकता है। – vale4674

+0

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

+0

के रूप में सरलीकृत किया जा सकता है; 'नई फ़ाइल (parentDirectoryUrl.getFile())' – Ducaz035

6

जैसा कि अन्य लोगों ने उल्लेख किया है, संसाधन क्लासलोडर के माध्यम से प्राप्त किए जाते हैं। क्या दो वर्तमान प्रतिक्रियाओं तनाव में विफल रहे हैं, हालांकि, इन बातों है:

  • ClassLoaders सार वर्गों और अन्य संसाधनों प्राप्त करने की प्रक्रिया के लिए होती हैं। संसाधन को फाइल सिस्टम में फ़ाइल नहीं होना चाहिए; यह एक दूरस्थ यूआरएल हो सकता है, या कुछ भी जो आप या किसी और को java.lang.ClassLoader बढ़ाकर लागू कर सकते हैं।
  • क्लासलोडर बच्चे/अभिभावक प्रतिनिधिमंडल श्रृंखला में मौजूद हैं। क्लासलोडर के लिए सामान्य व्यवहार माता-पिता से संसाधन प्राप्त करने का पहला प्रयास है, और उसके बाद केवल अपने संसाधनों को खोजें- लेकिन कुछ क्लासलोडर विपरीत क्रम (उदा।, सर्वलेट कंटेनर में) करते हैं।किसी भी मामले में, आपको सामानों को प्राप्त करने के लिए कौन सी क्लासलोडर की जगह की पहचान करना होगा, और फिर भी ऊपर या नीचे एक और क्लासलोडर आपके क्लाइंट कोड के संसाधन अनुरोधों को "चोरी" कर सकता है।
  • जैसा कि लियोनेल पोर्ट बताता है, यहां तक ​​कि एक क्लासलोडर में कई स्थान हो सकते हैं, जिससे यह सामान लोड करता है।
  • क्लासलोडर का उपयोग कक्षाओं को लोड करने के लिए किया जाता है। यदि आपका प्रोग्राम उन स्थानों पर फाइलें लिख सकता है जहां से कक्षाएं लोड की जाती हैं, तो यह आसानी से सुरक्षा जोखिम बन सकती है, क्योंकि उपयोगकर्ता के लिए आपके चल रहे एप्लिकेशन में कोड इंजेक्ट करना संभव हो सकता है।

लघु संस्करण: ऐसा न करें। संसाधनों की तरह सामानों की भंडार "के लिए सामान प्राप्त करने वाली सामग्री के भंडार" के लिए "सब कुछ प्राप्त कर सकते हैं" की उपनिवेश के लिए एक और अमूर्त इंटरफ़ेस लिखें, और "सब कुछ से सामान जोड़ने के लिए सबकुटरफेस" से सामान भी जोड़ सकते हैं। उत्तरार्द्ध को इस तरह से कार्यान्वित करें कि ClassLoader.getContextClassLoader().getResource() (क्लासपाथ को खोजने के लिए) का उपयोग करता है, और यदि यह विफल हो जाता है, तो कुछ अन्य तंत्र का उपयोग करने के लिए कुछ अन्य तंत्र का उपयोग करता है जो प्रोग्राम किसी स्थान से जोड़ा जा सकता है।

+0

@ sacundim मैंने अपना प्रश्न संपादित किया क्योंकि टिप्पणी बहुत बड़ी है। – vale4674

0

संकलित सबफ़ोल्डर के मुख्य प्रोजेक्ट फ़ोल्डर कट ("/ लक्ष्य/वर्गों", "लक्ष्य/परीक्षण वर्गों") और आप के साथ अपनी परियोजना फ़ोल्डरों को फिर से संगठित करने के लिए बुनियादी पथ:

import java.io.File; 
import java.io.IOException; 
import java.net.URISyntaxException; 

public class SubfolderCreator { 

public static void main(String... args) throws URISyntaxException, IOException { 
    File newResourceFolder = createResourceSubFolder("newFolder"); 
} 

private static File createResourceSubFolder(String folderName) throws URISyntaxException, IOException { 
    java.net.URL url = SubfolderCreator.class.getResource("/EXISTING_SUBFOLDER/"); 
    File fullPathToSubfolder = new File(url.toURI()).getAbsoluteFile(); 
    String projectFolder = fullPathToSubfolder.getAbsolutePath().split("target")[0]; 
    File testResultsFolder = new File(projectFolder + "src/test/resources/" + folderName); 
    if (!testResultsFolder.exists()) { 
     testResultsFolder.mkdir(); 
    } 
    return testResultsFolder; 
} 
} 
0

निम्नलिखित कोड कक्षा फ़ाइलों के साथ classes निर्देशिका में लिखते हैं।

जैसा कि अन्य ने ध्यान दिया है, क्लास फाइलों को ओवरराइट करने से सावधान रहें। अपनी नई फाइलों को एक अलग निर्देशिका में डालने के लिए सर्वश्रेष्ठ; हालांकि, उस निर्देशिका को पहले से मौजूद होना चाहिए। इसे बनाने के लिए, स्रोत में संसाधनों के भीतर एक उप-निर्देशिका बनाएं, शायद एक खाली फ़ाइल हो। उदाहरण के लिए src\main\resources\dir\empty.txt

public class WriteResource { 
    public static void main(String[] args) throws FileNotFoundException { 
     String thing = "Text to write to the file"; 
     String dir = WriteResource.class.getResource("/").getFile(); 
     //String dir = WriteResource.class.getResource("/dir").getFile(); 
     OutputStream os = new FileOutputStream(dir + "/file.txt"); 
     final PrintStream printStream = new PrintStream(os); 
     printStream.println(thing); 
     printStream.close(); 
    } 
} 

यह चाल है, लेकिन मैं इसे कड़ाई से नियंत्रित वातावरण के बाहर तैनात करने के बारे में परेशान होगा। मुझे वास्तव में अनधिकृत व्यक्तियों के विचार को मेरी classes निर्देशिका में लिखना पसंद नहीं है!