2012-01-08 4 views
86

모든 코드가 실행을 위해 보관되는 JAR 파일이 있습니다. 각 실행 전에 변경/편집해야 할 속성 파일에 액세스해야합니다. JAR 파일이있는 동일한 디렉토리에 특성 파일을 보관하려고합니다. Java가 해당 디렉토리에서 특성 파일을 선택하도록 알려줄 수 있습니까?JAR 파일 외부 속성 파일 읽기

참고 : 속성 파일을 홈 디렉터리에 보관하거나 명령 줄 인수에 속성 ​​파일의 경로를 전달하지 않으려합니다.

+0

[* 답변] (http://stackoverflow.com/a/5052359/418556) 참조 * 대신 "기본 파일을 Jar 파일에 저장하십시오. 다른 장소에서 변경된 파일. 하나의 일반적인 위치는'user.home'의 서브 디렉토리입니다. 파일을 검사 할 때 먼저 파일 시스템에 변경된 파일이 있는지 확인하고,없는 경우 기본 파일을로드하십시오. "* ** BTW ** *"나는 싫어합니다. " want는 응용 프로그램 디렉토리에 응용 프로그램 설정을 저장하는 것을 Oracle 및 MS (및 다른 사람들)가 강력하게 권장하지 않습니다. –

+2

jar 디렉토리에 등록 정보 파일을 유지해야하는 이유는 다음과 같습니다. 전체 디렉토리 (jar와 속성 포함)가 다른 머신에 복사되어 실행될 때 함께 보관하는 것이 더 좋습니다. – SoulMan

+0

그리고 사용자가 속성 파일 경로를 전달하도록 강요하면 배치를 실행할 때마다 변경해야합니다 파일 다른 기계에서. – SoulMan

답변

112

그래서, 당신은 파일로 주/실행 가능한 항아리와 같은 폴더에 대신의 리소스로 .properties 파일을 처리 할 main/runnable jar.

처음

우선 :

: 프로그램 파일 구조는 다음과 같이한다 (메인 프로그램이 main.jar의이고 그것의 주요 특성 파일을 가정이 main.properties입니다) 다음과 같은 경우에, 내 자신의 솔루션입니다
./ - the root of your program 
|__ main.jar 
|__ main.properties 

이 아키텍처에서는 main.jar이 실행 중일 때나 실행 중일 때 (프로그램의 현재 상태에 따라) 텍스트 기반이기 때문에 텍스트 편집기를 사용하여 main.properties 파일의 모든 속성을 수정할 수 있습니다 파일. 예를 들어, main.properties 파일에 포함 할 수 있습니다 : 당신이 루트/기본 폴더에서 메인 프로그램을 실행하면

app.version=1.0.0.0 
app.name=Hello 

그래서, 일반적으로이처럼 실행됩니다 :

java -jar ./main.jar 

또는, 바로 :

java -jar main.jar 

당신의 main.jar의에서, 당신은 당신의 main.properties 파일에있는 모든 속성에 대한 몇 가지 유틸리티 메서드를 만들어야합니다; 다음과 같이 app.version 값을 필요로하는 메인 프로그램의 어떤 부분에서

/** 
* Gets the app.version property value from 
* the ./main.properties file of the base folder 
* 
* @return app.version string 
* @throws IOException 
*/ 
public static String getAppVersion() throws IOException{ 

    String versionString = null; 

    //to load application's properties, we use this class 
    Properties mainProperties = new Properties(); 

    FileInputStream file; 

    //the base folder is ./, the root of the main.properties file 
    String path = "./main.properties"; 

    //load the file handle for main.properties 
    file = new FileInputStream(path); 

    //load all the properties from this file 
    mainProperties.load(file); 

    //we have loaded the properties, so close the file handle 
    file.close(); 

    //retrieve the property we are intrested, the app.version 
    versionString = mainProperties.getProperty("app.version"); 

    return versionString; 
} 

, 우리는 그 메소드를 호출 다음과 같이 app.version 속성이 getAppVersion() 방법이있을 것이다 가정 해 봅시다

String version = null; 
try{ 
    version = getAppVersion(); 
} 
catch (IOException ioe){ 
    ioe.printStackTrace(); 
} 
+7

이 솔루션은 작동합니다. 정확한 요구 사항 및 세부 코드를 이해해 주셔서 감사합니다. jar 파일 안에 속성 파일이 있지만 여전히 같은 디렉터에서 파일에 액세스 할 수 있는지 확인했습니다. y jar 파일이있는 곳. 이 방법으로 절대 경로 하드 코드가 필요하지 않습니다. jar 및 등록 정보 파일은 이제 모든 디렉토리에 복사하여 독립적으로 실행할 수 있습니다. – SoulMan

+1

ex : {{java -jar build/main.jar}}에 대해 외부에서 명령을 실행하면 파일을 찾을 수 없습니다. 그 문제에 대한 해결책이 있습니까? – Darian

+0

@Darian 여기서 고칠 것이 없습니다. 이것은 jar와 특성 파일이 파일 구조 아키텍처에서 설명한 것과 동일한'. /'루트 폴더 (동일한 디렉토리 레벨)에 있어야하는 설계된대로 작동합니다. (원래 게시자가 설정 한 요구 사항에 따라) – ecle

0

jar 파일에서 파일 디렉토리의 파일에 액세스 할 때 항상 문제가 있습니다. jar 파일에 classpath를 제공하는 것은 매우 제한적입니다. 대신 bat 파일이나 sh 파일을 사용하여 프로그램을 시작하십시오. 그렇게하면 시스템의 임의의 폴더를 참조하여 원하는대로 클래스 경로를 지정할 수 있습니다.

또한이 질문에 대한 내 대답을 확인하십시오

making .exe file for java project containing sqlite

27

I에 의해 그것을했다 다른 방법.

Properties prop = new Properties(); 
    try { 

     File jarPath=new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath()); 
     String propertiesPath=jarPath.getParentFile().getAbsolutePath(); 
     System.out.println(" propertiesPath-"+propertiesPath); 
     prop.load(new FileInputStream(propertiesPath+"/importer.properties")); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    } 
  1. 가져 오기 JAR 파일 경로.
  2. 해당 파일의 상위 폴더를 가져옵니다.
  3. InputStreamPath에서 해당 경로를 속성 파일 이름과 함께 사용하십시오.
+0

getParentFile() 부분을 삭제해야하므로 대신 다음을 사용했습니다. String propertiesPath = jarPath.getAbsolutePath(); 하지만 파일의 위치는 파일의 위치에 따라 다릅니다. – MobileMon

+2

"jarPath.getParentFile(). getAbsolutePath();" "jarPath.getParent()"로 변경하십시오. 그때 매력처럼 작동합니다. – StackAddict

+0

내 문제는 같지만 봄 기초 프로젝트가 있습니다. 파일이 jar 파일 옆에 있다는 것을 스프링에 알리는 방법은 무엇입니까? 어떤 생각 – Mubasher

0

비슷한 케이스가 있습니다 : *.jar 파일이 *.jar 파일 옆의 디렉토리에있는 파일에 액세스하려고합니다.THIS ANSWER도 참조하십시오.

내 파일 구조는 다음과 같습니다

./ - the root of your program 
|__ *.jar 
|__ dir-next-to-jar/some.txt 

나는 다음과 *.jar 파일 내부에의 InputStream에 파일 (예를 들어, some.txt를)로드 할 수 있어요 : 그런 다음 할

InputStream stream = null; 
    try{ 
     stream = ThisClassName.class.getClass().getResourceAsStream("/dir-next-to-jar/some.txt"); 
    } 
    catch(Exception e) { 
     System.out.print("error file to stream: "); 
     System.out.println(e.getMessage()); 
    } 

어떤 당신은 할 것입니다 stream