programing

Java에서 사용자의 홈 디렉토리를 찾는 가장 좋은 방법은 무엇입니까?

goodsources 2022. 8. 31. 22:53
반응형

Java에서 사용자의 홈 디렉토리를 찾는 가장 좋은 방법은 무엇입니까?

Java에서 사용자의 홈 디렉토리를 찾는 가장 좋은 방법은 무엇입니까?

어려운 점은 솔루션이 크로스 플랫폼이어야 한다는 것입니다.Windows 2000, XP, Vista, OS X, Linux 및 기타 Unix 버전에서 동작해야 합니다.모든 플랫폼에서 이를 수행할 수 있는 코드 조각과 플랫폼을 탐지할 수 있는 방법을 찾고 있습니다.

Java bug 4787931에 따라 시스템 속성user.home는 Windows XP에서 올바르게 동작하지 않기 때문에 이 시스템속성을 사용하는 것은 크로스 플랫폼이 아니기 때문에 허용되지 않는 솔루션입니다.

참조한 버그(버그 4787391)는 Java 8에서 수정되었습니다.이전 버전의 Java를 사용하는 경우에도System.getProperty("user.home")접근 방식이 여전히 최선일 것입니다.user.home접근방식은 매우 많은 경우에 효과가 있는 것 같습니다.Windows 에서의 100% 방탄 솔루션은, Windows 에서는 홈 디렉토리의 의미에 대한 개념이 변화하고 있기 때문에, 어려운 일입니다.

한다면user.home당신에게는 충분하지 않습니다. 저는 그 정의를 선택할 것을 제안합니다.home directory적절한 환경변수를 입수하여 사용하는 경우System.getenv(String).

실제로 Java 8에서는 다음을 사용하는 것이 좋습니다.

System.getProperty("user.home");

버그 JDK-6519127은 수정되었으며 릴리스 노트의 "JDK 8과 JDK 7 사이의 호환성" 섹션에 다음과 같이 기재되어 있습니다.

영역: 코어 립스 / java.lang

개요

Windows 로 유저의 홈 디렉토리를 판별하기 위해서 사용하는 순서는, Microsoft 의 추천 어프로치에 따라서 변경되었습니다.이 변경은 이전 버전의 윈도우즈나 레지스트리 설정 또는 환경 변수가 다른 디렉터리로 설정된 경우 관찰할 수 있습니다.비호환성 특성

behavioral RFE

6519127

오래된 질문이긴 하지만 나중에 참고할 수 있도록 남겨두겠습니다.

System.getProperty("user.home");

Java Doc 를 참조해 주세요.

Windows 에서는, HOME 디렉토리의 개념이 애매한 것 같습니다.환경변수(HOMEDRIVE/HOMEPATH/USERPROFILE)가 충분하지 않은 경우 JNI 또는 JNA를 통해 네이티브 기능을 사용해야 합니다.SHGetFolderPath를 사용하면 My Documents(CSIDL_Personal)나 Local Settings(로컬 설정)와 같은 특수 폴더를 검색할 수 있습니다.\\응용 프로그램 데이터(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);

    }

}

이전에 다른 사용자가 질문에 답했지만 사용 가능한 모든 속성을 인쇄하는 데 유용한 프로그램은 다음과 같습니다.

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

방법은 Apache Commons를 입니다. ★★★★FileUtils.getUserDirectory()System.getProperty("user.home")같은 결과를 얻을 수 있어 시스템 속성을 지정할 때 오타가 발생할 가능성은 없습니다.

Apache Commons를 이미 가지고 있을 가능성이 큽니다.프로젝트의 IO 라이브러리.유저 홈 디렉토리를 취득하기 위해서만 사용하는 경우는, 도입하지 말아 주세요.

스칼라 버전을 찾았을 때, 내가 찾을 수 있는 것은 위의 맥도웰의 유고 인민군 코드뿐이었다.현재 적절한 포트가 없기 때문에 여기에 Scala 포트를 포함합니다.

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")
            })
        }
    }
}

Java 버전과 마찬가지로 Java Native Access를 참조 라이브러리에 추가해야 합니다.

이제 유고 인민군이 원래 코드가 게시되었을 때보다 훨씬 쉽게 만든다는 것은 좋은 일이다.

버그 리포트에 기재되어 있는 알고리즘을 System을 사용하여 사용합니다.유효한 기존 디렉토리를 나타내는 환경변수가 없는 경우 getenv(String) 및 user.dir 속성을 사용하여 폴백합니다.이것은 크로스 플랫폼에서도 동작합니다.

Windows 에서는, 유저의 「문서」디렉토리가 정말로 필요한 것 같습니다.

윈도에서 잘 작동하는 것을 원한다면 윈폴더자바라는 패키지가 있습니다.이 패키지는 네이티브 콜을 랩하여 윈도에서 '특별한' 디렉토리를 가져옵니다.자주 사용하고 있고, 잘 작동합니다.

언급URL : https://stackoverflow.com/questions/585534/what-is-the-best-way-to-find-the-users-home-directory-in-java

반응형