জাভাতে ব্যবহারকারীদের হোম ডিরেক্টরি খুঁজে পাওয়ার সর্বোত্তম উপায় কী?


279

অসুবিধাটি হ'ল এটি ক্রস প্ল্যাটফর্ম হওয়া উচিত। উইন্ডোজ 2000, এক্সপি, ভিস্তা, ওএসএক্স, লিনাক্স, অন্যান্য ইউনিক্স রূপগুলি। আমি কোডের একটি স্নিপেট খুঁজছি যা এটি সমস্ত প্ল্যাটফর্মের জন্য এটি সম্পাদন করতে পারে এবং প্ল্যাটফর্ম সনাক্ত করার একটি উপায়।

এখন, আপনি সচেতন হওয়া উচিত বাগ 4787931 যে user.homeসঠিকভাবে কাজ করে না, তাই আমাকে পাঠ্যপুস্তক উত্তর প্রদান করবেন না দয়া করে, আমি এই নিজেকে ম্যানুয়াল খুঁজে পেতে পারেন।


1
আপনি বাগে উল্লিখিত ওয়ার্কআরউন্ডগুলি ব্যবহার করে দেখেছেন? প্রচুর পরামর্শ আছে।
জোছিম সউর

1
জাভা সংস্করণগুলির জন্য 1.4.2 এর মাধ্যমে বাগ 4787931 আবার জাভা 1.6 এর জন্য বাগ 6519127 হিসাবে আবার প্রদর্শিত হবে। সমস্যাটি সরে যাচ্ছে না এবং এখনও কম অগ্রাধিকার হিসাবে তালিকাভুক্ত।
গ্রেগএ 100k

16
দ্রষ্টব্য: বাগ 4787391 জাভা 8
স্টিভেন আর লুমিস

উত্তর:


364

আপনি যে বাগটি উল্লেখ করেছেন (বাগ 4787391) সেটি জাভা ৮ এ স্থির করা হয়েছে। এমনকি আপনি জাভাটির কোনও পুরানো সংস্করণ ব্যবহার করছেন, তবে 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 এর মধ্যে অসঙ্গতি" রিলিজ নোটগুলির বিভাগে বলা হয়েছে:

অঞ্চল: কোর লিবস / জাভা.লং

সংক্ষিপ্তসার

উইন্ডোজে ব্যবহারকারীর হোম ডিরেক্টরি নির্ধারণের জন্য ব্যবহৃত পদক্ষেপগুলি মাইক্রোসফ্টের প্রস্তাবিত পদ্ধতির অনুসরণ করতে পরিবর্তিত হয়েছে। এই পরিবর্তনটি উইন্ডোজের পুরানো সংস্করণগুলিতে বা যেখানে রেজিস্ট্রি সেটিংস বা পরিবেশের ভেরিয়েবলগুলি অন্য ডিরেক্টরিতে সেট করা আছে সেখানে পর্যবেক্ষণযোগ্য হতে পারে। অসঙ্গতি প্রকৃতি

behavioral RFE

6519127

প্রশ্নটি পুরানো হওয়া সত্ত্বেও আমি এটি ভবিষ্যতের রেফারেন্সের জন্য রেখেছি।


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

জাভাডোক দেখুন ।


11
না, সঠিক উত্তর নয়, এটি উপরের মতো একই। হ্যাঁ, আমি কেবল জাভাডকগুলিই পড়িনি, তবে এই প্রশ্নটি জিজ্ঞাসা করার আগে আমি সমস্ত প্ল্যাটফর্মেও চেষ্টা করে দেখেছি! উত্তরটি এত সহজ নয়।
ব্রুনো র্যানচেয়ার্ট

3
এটি উইন্ডোজগুলিতে মারাত্মকভাবে ভুল হতে পারে, যেখানে এটি কেবলমাত্র ডেস্কটপ ডিরেক্টরিটির পিতামাতাকে গ্রহণ করবে, যা যে কোনও জায়গায় হতে পারে ...
ক্রনিকাল

29

উইন্ডোজের কথা বলতে গেলে কোনও হোম ডিরেক্টরি ধারণাটি কিছুটা অস্পষ্ট বলে মনে হয়। তাহলে এনভায়রনমেন্ট ভেরিয়েবল (HOMEDRIVE / HOMEPATH / USERPROFILE) যথেষ্ট নয়, আপনি মাধ্যমে নেটিভ ফাংশন ব্যবহার করে অবলম্বন করতে হতে পারে JNI বা JNASHGetFolderPath আপনাকে আমার ডকুমেন্টস (CSIDL_PERSONAL) বা স্থানীয় সেটিংস \ অ্যাপ্লিকেশন ডেটা (CSIDL_LOCAL_APPDATA) এর মতো বিশেষ ফোল্ডারগুলি পুনরুদ্ধার করার অনুমতি দেয় ।

নমুনা জেএনএ কোড:

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);

    }

}

এফওয়াইআই, ফোল্ডারটি যা ব্যবহারকারীর হোম ডিরেক্টরিটির সাথে সম্পর্কিত, তা হ'ল সিএসআইডিএল_প্রোফাইল। এমএসডিএন.মাইক্রোসফটকম /en-us/library/bb762494(VS.85).aspx দেখুন ।
ম্যাট সলনিট

হ্যাঁ, এটি উইন্ডোজের ক্ষেত্রে বিস্তৃত সংস্করণ।
ব্রুনো র্যানচেয়ার্ট

2
জেএনএর সাম্প্রতিক সংস্করণগুলিতে (আরও সুনির্দিষ্টভাবে জেনা-প্ল্যাটফর্ম), এখানে একটি শেল 32 ইউটি ক্লাস রয়েছে যা সম্পর্কিত উইন্ডোজ এপিআইটিকে খুব সুন্দর উপায়ে নিয়ে যায়। বিশেষত, জ্ঞাত ফোল্ডার শ্রেণীর যে কোনও ধ্রুবকের সাথে সম্মিলিতভাবে Shell32Util.getKজ্ঞানফোল্ডারপাথ (...) ব্যবহার করা উপযুক্ত হওয়া উচিত। পুরানো getFolderPath API ফাংশনটি উইন্ডোজ ভিস্তার থেকে অবচয় করা হয়েছে।
সেবাস্তিয়ান মার্শিং

17

অন্যরা আমার আগে প্রশ্নের উত্তর দিয়েছেন তবে সমস্ত উপলব্ধ সম্পত্তি মুদ্রণের জন্য একটি কার্যকর প্রোগ্রামটি হ'ল:

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

আমি এটির উপর নির্ভর করব না, কারণ সমস্ত সম্পত্তি মানসম্মত নয়। পরিবর্তে সিস্টেমের জন্য জাভডোক পরীক্ষা করুন getgetProperties () কোন বৈশিষ্ট্যের অস্তিত্বের নিশ্চয়তা রয়েছে তা সন্ধান করার জন্য।
জোছিম সউর

6
এটি সত্য হতে পারে তবে আমি মনে করি এমন একটি নবজাতকের পক্ষে এটি এখনও বেশ কার্যকর! আমি নিশ্চিত নই যে এটি 2
ডাউনভোটের

6

আমি যখন স্কালাল সংস্করণটি অনুসন্ধান করছিলাম, তখন আমি ম্যাকডোভেলের জেএনএ কোডটি উপরে পেয়েছি। আমি এখানে আমার স্কালা বন্দরটি অন্তর্ভুক্ত করেছি, কারণ বর্তমানে এখানে কোথাও উপযুক্ত নেই isn't

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

আমি সিস্টেম.জেটেনভ (স্ট্রিং) ব্যবহার করে বাগ রিপোর্টে বিস্তারিত অ্যালগরিদম ব্যবহার করব এবং ইউজার.ডির সম্পত্তি ব্যবহার করতে পারব যদি পরিবেশের ভেরিয়েবলগুলির মধ্যে কোনওটি বৈধ বিদ্যমান ডিরেক্টরি নির্দেশ না করে। এটি ক্রস প্ল্যাটফর্ম কাজ করা উচিত।

আমি মনে করি, উইন্ডোজ এর অধীনে, আপনি আসলে যা পরে ব্যবহারকারীর কল্পিত "নথি" ডিরেক্টরি।


2

বিকল্পটি FileUtils.getUserDirectory()পরিবর্তে অ্যাপাচি কমন্সআইও ব্যবহার করা হবে System.getProperty("user.home")। এটি আপনাকে একই ফলাফল দেবে এবং সিস্টেমের সম্পত্তি উল্লেখ করার সময় টাইপো চালু করার কোনও সুযোগ নেই।

আপনার প্রকল্পে ইতিমধ্যে অ্যাপাচি কমন্সআইও গ্রন্থাগার রয়েছে এমন একটি বড় সম্ভাবনা রয়েছে। আপনি যদি কেবল এটির ব্যবহারকারী ডিরেক্টরি পাওয়ার জন্য এটি ব্যবহার করার পরিকল্পনা করেন তবে এটি পরিচয় করিয়ে দিন না।


0

আপনি যদি উইন্ডোজে ভালভাবে কাজ করে এমন কিছু চান তবে উইনফোল্ডারস জাভা নামে একটি প্যাকেজ রয়েছে যা উইন্ডোজে 'বিশেষ' ডিরেক্টরিগুলি পাওয়ার জন্য নেটিভ কলটি আবৃত করে। আমরা এটি ঘন ঘন ব্যবহার করি এবং এটি ভালভাবে কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.