जावा में उपयोगकर्ताओं की होम निर्देशिका को खोजने का सबसे अच्छा तरीका क्या है?


279

मुश्किल यह है कि यह क्रॉस प्लेटफॉर्म होना चाहिए। विंडोज 2000, एक्सपी, विस्टा, ओएसएक्स, लिनक्स, अन्य यूनिक्स वेरिएंट। मैं कोड का एक स्निपेट ढूंढ रहा हूं जो सभी प्लेटफार्मों के लिए यह पूरा कर सके, और मंच का पता लगाने का एक तरीका।

अब, आपको बग 4787931 के बारे में पता होना चाहिए जो user.homeसही तरीके से काम नहीं करता है, इसलिए कृपया मुझे पाठ्यपुस्तक के उत्तर प्रदान न करें, मैं स्वयं इन पुस्तिकाओं में पा सकता हूं।


1
क्या आपने बग में बताए गए वर्कअराउंड की कोशिश की? सुझाव बहुत हैं।
Joachim Sauer

1
बग संस्करण के लिए बग 4787931, 1.4.2 के माध्यम से जावा 1.6 के लिए बग 6519127 के रूप में फिर से दिखाई देता है। समस्या दूर नहीं हो रही है और अभी भी निम्न प्राथमिकता के रूप में सूचीबद्ध है।
ग्रेग 100k 15

16
नोट: बग 4787391 को जावा 8 में तय किया गया है
स्टीवन आर। लूमिस

जवाबों:


364

जिस बग का आप संदर्भ देते हैं (बग 4787391) जावा 8 में तय किया गया है। भले ही आप जावा के पुराने संस्करण का उपयोग कर रहे हों, लेकिन System.getProperty("user.home")दृष्टिकोण अभी भी सबसे अच्छा है। यह user.homeदृष्टिकोण बहुत बड़ी संख्या में काम करता है। विंडोज पर 100% बुलेटप्रूफ समाधान कठिन है, क्योंकि विंडोज में होम डाइरेक्टरी का एक शिफ्टिंग कॉन्सेप्ट है।

यदि user.homeआपके लिए पर्याप्त नहीं है, तो मैं सुझाव दूंगा कि आप home directoryविंडोज़ के लिए परिभाषा का चयन करें और इसका उपयोग करते हुए, उचित पर्यावरण चर प्राप्त करें System.getenv(String)


135

वास्तव में जावा 8 का सही तरीका उपयोग करना है:

System.getProperty("user.home");

बग JDK-6519127 को ठीक कर दिया गया है और "JDK 8 और JDK 7 के बीच असंगतताएं" जारी किए गए नोटों का खंड कहता है:

क्षेत्र: कोर Libs / java.lang

सार

विंडोज पर उपयोगकर्ता की होम निर्देशिका को निर्धारित करने के लिए उपयोग किए जाने वाले कदम Microsoft अनुशंसित दृष्टिकोण का पालन करने के लिए बदल गए हैं। यह परिवर्तन विंडोज के पुराने संस्करणों पर या जहां रजिस्ट्री सेटिंग या पर्यावरण चर अन्य निर्देशिकाओं पर सेट किए गए हैं, पर अवलोकन योग्य हो सकते हैं। असंगति की प्रकृति

behavioral RFE

6519127

प्रश्न पुराना होने के बावजूद मैं इसे भविष्य के संदर्भ के लिए छोड़ देता हूं।


35
System.getProperty("user.home");

JavaDoc देखें ।


11
नहीं, एक सही जवाब नहीं है, यह ऊपर के रूप में एक ही है। हां, मैंने न केवल JavaDocs पढ़ी, बल्कि मैंने यह सवाल पूछने से पहले इसे सभी प्लेटफार्मों पर आजमाया! इसका जवाब इतना आसान नहीं है।
ब्रूनो रैनशर्ट

3
यह खिड़कियों पर बुरी तरह से गलत हो सकता है, जहां यह सिर्फ डेस्कटॉप निर्देशिका के माता-पिता को ले जाएगा, जो कहीं भी हो सकता है ...
15:12 पर क्रोनिकल

29

एक गृह निर्देशिका की अवधारणा थोड़ा सा अस्पष्ट है जब यह विंडोज की बात आती है। यदि पर्यावरण चर (HOMEDRIVE / HOMEPATH / USERPROFILE) पर्याप्त नहीं हैं, तो आपको जेएनआई या जेएनए के माध्यम से मूल कार्यों का उपयोग करना पड़ सकता है । SHGetFolderPath आपको विशेष फ़ोल्डर, जैसे मेरा दस्तावेज़ (CSIDL_PERSONAL) या स्थानीय सेटिंग \ Application Data (CSIDL_LOCAL_APPDATA) प्राप्त करने देता है।

नमूना JNA कोड:

public class PrintAppDataDir {

    public static void main(String[] args) {
        if (com.sun.jna.Platform.isWindows()) {
            HWND hwndOwner = null;
            int nFolder = Shell32.CSIDL_LOCAL_APPDATA;
            HANDLE hToken = null;
            int dwFlags = Shell32.SHGFP_TYPE_CURRENT;
            char[] pszPath = new char[Shell32.MAX_PATH];
            int hResult = Shell32.INSTANCE.SHGetFolderPath(hwndOwner, nFolder,
                    hToken, dwFlags, pszPath);
            if (Shell32.S_OK == hResult) {
                String path = new String(pszPath);
                int len = path.indexOf('\0');
                path = path.substring(0, len);
                System.out.println(path);
            } else {
                System.err.println("Error: " + hResult);
            }
        }
    }

    private static Map<String, Object> OPTIONS = new HashMap<String, Object>();
    static {
        OPTIONS.put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
        OPTIONS.put(Library.OPTION_FUNCTION_MAPPER,
                W32APIFunctionMapper.UNICODE);
    }

    static class HANDLE extends PointerType implements NativeMapped {
    }

    static class HWND extends HANDLE {
    }

    static interface Shell32 extends Library {

        public static final int MAX_PATH = 260;
        public static final int CSIDL_LOCAL_APPDATA = 0x001c;
        public static final int SHGFP_TYPE_CURRENT = 0;
        public static final int SHGFP_TYPE_DEFAULT = 1;
        public static final int S_OK = 0;

        static Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32",
                Shell32.class, OPTIONS);

        /**
         * see http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx
         * 
         * HRESULT SHGetFolderPath( HWND hwndOwner, int nFolder, HANDLE hToken,
         * DWORD dwFlags, LPTSTR pszPath);
         */
        public int SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken,
                int dwFlags, char[] pszPath);

    }

}

FYI करें, वह फ़ोल्डर जो उपयोगकर्ता की होम डायरेक्टरी से मेल खाता है CSIDL_PROFILE है। Msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx देखें ।
मैट सोलनीट

हां, यह विंडोज केस के लिए एक विस्तृत संस्करण है।
ब्रूनो रैनशर्ट

2
जेएनए के हाल के संस्करणों में (अधिक सटीक रूप से jna-platform), एक Shell32Util वर्ग है जो संबंधित Windows API को बहुत अच्छे तरीके से एन्क्रिप्ट करता है। विशेष रूप से, Shell32Util.getKnownFolderPath (...) का उपयोग करते हुए KnownFolders वर्ग में से एक कॉन्स्टेंट के साथ संयोजन उपयुक्त होना चाहिए। पुराने getFolderPath API फ़ंक्शन को Windows Vista के बाद से हटा दिया गया है।
सेबेस्टियन मार्शचिंग

17

अन्य लोगों ने मेरे सामने प्रश्न का उत्तर दिया है लेकिन सभी उपलब्ध संपत्तियों को प्रिंट करने के लिए एक उपयोगी कार्यक्रम है:

for (Map.Entry<?,?> e : System.getProperties().entrySet()) {
    System.out.println(String.format("%s = %s", e.getKey(), e.getValue())); 
}

मैं इस पर निर्भर नहीं होता, क्योंकि सभी गुण मानकीकृत नहीं हैं। इसके बजाय JavaDoc को System.getProperties () के लिए यह पता लगाने के लिए जांचें कि कौन से गुण मौजूद हैं।
जोकिम सॉयर

6
यह सच हो सकता है लेकिन मुझे लगता है कि यह नौसिखिया के लिए अभी भी बहुत उपयोगी है! मुझे यकीन नहीं है कि यह 2
डाउनवोट्स का

6

जैसा कि मैं स्काला संस्करण की खोज कर रहा था, सभी मुझे मिल सकता था मैकडॉवेल का जेएनए कोड ऊपर था। मैं अपने स्काला पोर्ट को यहां शामिल करता हूं, क्योंकि वर्तमान में कहीं भी अधिक उपयुक्त नहीं है।

import com.sun.jna.platform.win32._
object jna {
    def getHome: java.io.File = {
        if (!com.sun.jna.Platform.isWindows()) {
            new java.io.File(System.getProperty("user.home"))
        }
        else {
            val pszPath: Array[Char] = new Array[Char](WinDef.MAX_PATH)
            new java.io.File(Shell32.INSTANCE.SHGetSpecialFolderPath(null, pszPath, ShlObj.CSIDL_MYDOCUMENTS, false) match {
                case true => new String(pszPath.takeWhile(c => c != '\0'))
                case _    => System.getProperty("user.home")
            })
        }
    }
}

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

यह देखकर अच्छा लगा कि जेएनए अब मूल कोड पोस्ट किए जाने की तुलना में इसे बहुत आसान बनाता है।


2

मैं System.getenv (स्ट्रिंग) का उपयोग करके बग रिपोर्ट में विस्तृत एल्गोरिथ्म का उपयोग करूंगा, और user.dir संपत्ति का उपयोग करने के लिए कमबैक करूंगा यदि कोई भी पर्यावरण चर एक मौजूदा मौजूदा निर्देशिका को इंगित नहीं करता है। इसके लिए क्रॉस-प्लेटफॉर्म पर काम करना चाहिए।

मुझे लगता है, विंडोज के तहत, आप वास्तव में उपयोगकर्ता की "दस्तावेज़" निर्देशिका के बाद क्या कर रहे हैं।


2

वैकल्पिक के FileUtils.getUserDirectory()बजाय Apache CommonsIO का उपयोग करना होगा System.getProperty("user.home")। यह आपको समान परिणाम देगा और सिस्टम प्रॉपर्टी को निर्दिष्ट करते समय टाइपो को पेश करने का कोई मौका नहीं है।

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


0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.