File
दिए गए के लिए प्राप्त करने के लिए Class
, दो चरण हैं:
- कन्वर्ट
Class
एक करने के लिएURL
- कन्वर्ट
URL
एक करने के लिएFile
दोनों चरणों को समझना महत्वपूर्ण है, न कि उन्हें स्वीकार करना।
आपके पास एक बार File
, आप getParentFile
युक्त फ़ोल्डर प्राप्त करने के लिए कॉल कर सकते हैं , यदि ऐसा है तो आपको आवश्यकता है।
चरण 1: Class
सेURL
जैसा कि अन्य उत्तरों में चर्चा की गई है, एक URL
प्रासंगिक को खोजने के दो प्रमुख तरीके हैं Class
।
URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
दोनों के पक्ष और विपक्ष हैं।
getProtectionDomain
दृष्टिकोण वर्ग (जैसे, युक्त JAR फ़ाइल) के आधार स्थान अर्जित करता है। हालांकि, यह संभव है कि जावा रनटाइम की सुरक्षा नीति SecurityException
कॉल करते समय फेंक देगी getProtectionDomain()
, इसलिए यदि आपके एप्लिकेशन को विभिन्न प्रकार के वातावरण में चलाने की आवश्यकता है, तो उन सभी में परीक्षण करना सबसे अच्छा है।
getResource
दृष्टिकोण वर्ग, जिसमें से आप अतिरिक्त स्ट्रिंग हेरफेर करने की आवश्यकता होगी के पूर्ण URL संसाधन पथ अर्जित करता है। यह एक file:
रास्ता हो सकता है , लेकिन यह OSGi ढांचे के भीतर निष्पादित करते समय jar:file:
कुछ नास्टियर भी हो सकता है bundleresource://346.fwk2106232034:4/foo/Bar.class
। इसके विपरीत, getProtectionDomain
दृष्टिकोण सही ढंग file:
से OSGi से भी एक URL देता है।
ध्यान दें कि दोनों getResource("")
और getResource(".")
मेरे परीक्षण में विफल रहा है, जब वर्ग एक जार फ़ाइल के भीतर बसता; दोनों आह्वान शून्य हो गए। इसलिए मैं इसके बजाय ऊपर दिखाए गए # 2 आह्वान की सलाह देता हूं, क्योंकि यह अधिक सुरक्षित लगता है।
चरण 2: URL
सेFile
किसी भी तरह से, एक बार आपके पास URL
, अगला चरण एक में बदल जाता है File
। यह इसकी अपनी चुनौती है; देख इसके बारे में Kohsuke कावागुची के ब्लॉग पोस्ट पूर्ण विवरण के लिए, लेकिन संक्षेप में, आप उपयोग कर सकते हैं new File(url.toURI())
जब तक कि पूरी तरह से यूआरएल अच्छी तरह से ही बना है।
अंत में, मैं अत्यधिक उपयोग को हतोत्साहित करूंगा URLDecoder
। URL के कुछ वर्ण :
और /
विशेष रूप से, मान्य URL-एन्कोड किए गए वर्ण नहीं हैं। से URLDecoder जावाडोक:
यह माना जाता है कि एन्कोडेड स्ट्रिंग के सभी वर्ण निम्न में से एक हैं: "a" "z", "A" के माध्यम से "Z", "0" के माध्यम से "9", और "-", "_", " ।", तथा "*"। चरित्र "%" की अनुमति है, लेकिन एक विशेष बच गए अनुक्रम की शुरुआत के रूप में व्याख्या की गई है।
...
ऐसे दो संभावित तरीके हैं जिनसे यह डिकोडर अवैध तारों से निपट सकता है। यह या तो अवैध चरित्रों को अकेला छोड़ सकता है या यह एक अवैध अवैध व्यापार को फेंक सकता है। जो डिकोडर लेता है वह कार्यान्वयन के लिए छोड़ दिया जाता है।
व्यवहार में, URLDecoder
आम तौर पर IllegalArgumentException
ऊपर धमकी के रूप में नहीं फेंकता है। और यदि आपके फ़ाइल पथ में रिक्त स्थान हैं %20
, तो यह दृष्टिकोण काम कर सकता है। हालाँकि, यदि आपकी फ़ाइल पथ में अन्य गैर-अल्फ़ॉर्म वर्ण हैं जैसे कि +
आपको अपने फ़ाइल पथ को प्रबंधित करने में समस्याएँ होंगी URLDecoder
।
कार्य कोड
इन चरणों को प्राप्त करने के लिए, आपके पास निम्नलिखित जैसे तरीके हो सकते हैं:
/**
* Gets the base location of the given class.
* <p>
* If the class is directly on the file system (e.g.,
* "/path/to/my/package/MyClass.class") then it will return the base directory
* (e.g., "file:/path/to").
* </p>
* <p>
* If the class is within a JAR file (e.g.,
* "/path/to/my-jar.jar!/my/package/MyClass.class") then it will return the
* path to the JAR (e.g., "file:/path/to/my-jar.jar").
* </p>
*
* @param c The class whose location is desired.
* @see FileUtils#urlToFile(URL) to convert the result to a {@link File}.
*/
public static URL getLocation(final Class<?> c) {
if (c == null) return null; // could not load the class
// try the easy way first
try {
final URL codeSourceLocation =
c.getProtectionDomain().getCodeSource().getLocation();
if (codeSourceLocation != null) return codeSourceLocation;
}
catch (final SecurityException e) {
// NB: Cannot access protection domain.
}
catch (final NullPointerException e) {
// NB: Protection domain or code source is null.
}
// NB: The easy way failed, so we try the hard way. We ask for the class
// itself as a resource, then strip the class's path from the URL string,
// leaving the base path.
// get the class's raw resource path
final URL classResource = c.getResource(c.getSimpleName() + ".class");
if (classResource == null) return null; // cannot find class resource
final String url = classResource.toString();
final String suffix = c.getCanonicalName().replace('.', '/') + ".class";
if (!url.endsWith(suffix)) return null; // weird URL
// strip the class's path from the URL string
final String base = url.substring(0, url.length() - suffix.length());
String path = base;
// remove the "jar:" prefix and "!/" suffix, if present
if (path.startsWith("jar:")) path = path.substring(4, path.length() - 2);
try {
return new URL(path);
}
catch (final MalformedURLException e) {
e.printStackTrace();
return null;
}
}
/**
* Converts the given {@link URL} to its corresponding {@link File}.
* <p>
* This method is similar to calling {@code new File(url.toURI())} except that
* it also handles "jar:file:" URLs, returning the path to the JAR file.
* </p>
*
* @param url The URL to convert.
* @return A file path suitable for use with e.g. {@link FileInputStream}
* @throws IllegalArgumentException if the URL does not correspond to a file.
*/
public static File urlToFile(final URL url) {
return url == null ? null : urlToFile(url.toString());
}
/**
* Converts the given URL string to its corresponding {@link File}.
*
* @param url The URL to convert.
* @return A file path suitable for use with e.g. {@link FileInputStream}
* @throws IllegalArgumentException if the URL does not correspond to a file.
*/
public static File urlToFile(final String url) {
String path = url;
if (path.startsWith("jar:")) {
// remove "jar:" prefix and "!/" suffix
final int index = path.indexOf("!/");
path = path.substring(4, index);
}
try {
if (PlatformUtils.isWindows() && path.matches("file:[A-Za-z]:.*")) {
path = "file:/" + path.substring(5);
}
return new File(new URL(path).toURI());
}
catch (final MalformedURLException e) {
// NB: URL is not completely well-formed.
}
catch (final URISyntaxException e) {
// NB: URL is not completely well-formed.
}
if (path.startsWith("file:")) {
// pass through the URL as-is, minus "file:" prefix
path = path.substring(5);
return new File(path);
}
throw new IllegalArgumentException("Invalid URL: " + url);
}
आप SciJava आम पुस्तकालय में इन विधियों को पा सकते हैं :