2012-01-08 13 views
86

Ho un file JAR in cui tutto il mio codice è archiviato per l'esecuzione. Devo accedere a un file delle proprietà che deve essere modificato/modificato prima di ogni corsa. Voglio mantenere il file delle proprietà nella stessa directory in cui si trova il file JAR. C'è comunque da dire a Java di prendere il file delle proprietà da quella directory?Lettura file di proprietà all'esterno del file JAR

Nota: non desidero mantenere il file delle proprietà nella directory principale o passare il percorso del file delle proprietà nell'argomento della riga di comando.

+0

Vedere [questa risposta] (http://stackoverflow.com/a/5052359/418556) - * "Memorizza invece il file 'predefinito' all'interno del Jar. Se viene modificato, salva il file alterato in un altro posto. Un luogo comune è una sottodirectory di 'user.home'. Quando verifichi il file, controlla prima l'esistenza di un file alterato sul file system e, se non esiste, carica il file predefinito. "* ** BTW ** *" Non voglio ... "* Cosa vuoi il desiderio è meno importante di ciò che funziona ed è pratico. La memorizzazione delle impostazioni dell'app nella directory dell'applicazione è fortemente sconsigliata da Oracle & MS (e probabilmente da altri) –

+2

Il motivo per cui ho bisogno di mantenere il file delle proprietà nella directory jar è che è meglio tenerli insieme quando l'intera directory (incluso jar e proprietà) viene copiata su un'altra macchina ed eseguita. – SoulMan

+0

E se costringo l'utente a passare il percorso del file delle proprietà, allora deve cambiarlo ogni volta che esegue il batch file da una macchina diversa. – SoulMan

risposta

112

Quindi, si vuole trattare il file .properties sulla stessa cartella del vaso principale/eseguibile come un file piuttosto che come una risorsa della barattolo principale/eseguibile. In tal caso, la mia soluzione è la seguente:

Per prima cosa: l'architettura di file di programma deve essere simile a questo (supponendo che il programma principale è main.jar e il file le sue proprietà principali è main.properties):

Con questa architettura, è possibile modificare qualsiasi proprietà nel file main.properties utilizzando qualsiasi editor di testo prima o mentre il file main.jar è in esecuzione (a seconda dello stato corrente del programma) poiché si tratta solo di un testo file. Ad esempio, il file può contenere main.properties:

app.version=1.0.0.0 
app.name=Hello 

Così, quando si esegue il programma principale dalla sua cartella principale/base, normalmente vi imbatterete in questo modo:

java -jar ./main.jar 

o, subito:

java -jar main.jar 

nella tua main.jar, è necessario creare un paio di metodi di utilità per ogni proprietà trovata in file main.properties; diciamo la proprietà app.version avrà getAppVersion() metodo come segue:

/** 
* 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; 
} 

In ogni parte del programma principale che ha bisogno il valore app.version, abbiamo chiamare il suo metodo come segue:

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

Questa soluzione funziona. Grazie per aver compreso il requisito esatto e il codice dettagliato. Ho verificato che il file delle proprietà non si trova all'interno del file jar ma può ancora accedere al file dallo stesso director y dove si trova il file jar. In questo modo non è necessario il codice hard del percorso assoluto. Ora sia il file jar che il file delle proprietà possono essere copiati in qualsiasi directory ed eseguiti indipendentemente. – SoulMan

+1

Il file non verrà trovato se si esegue il comando dall'esterno per ex: {{java -jar build/main.jar}}. Hai qualche soluzione per questo, @eee? – Darian

+0

@Darian Non c'è niente da sistemare qui; Funziona solo come progettato dove il jar e il file delle proprietà devono trovarsi nella stessa cartella '. /' Root (stesso livello di directory) rispetto a ciò che ho descritto nell'architettura dell'organizzazione dei file. (come da requisiti stabiliti dal poster originale) – ecle

0

C'è sempre un problema nell'accedere ai file nella directory dei file da un file jar. Fornire il classpath in un file jar è molto limitato. Prova invece a utilizzare un file bat o un file sh per avviare il programma. In questo modo è possibile specificare il classpath in ogni caso, facendo riferimento a qualsiasi cartella in qualsiasi punto del sistema.

Controllare anche la mia risposta su questa questione:

making .exe file for java project containing sqlite

27

ho fatto da altro modo.

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. ottenere il percorso del file Jar.
  2. Ottieni cartella principale di quel file.
  3. Utilizzare quel percorso in InputStreamPath con il nome del file delle proprietà.
+0

Ho dovuto eliminare la parte getParentFile(), quindi ho usato: String propertiesPath = jarPath.getAbsolutePath(); ma tutto dipende da dove si trova il file – MobileMon

+2

Basta sostituire "jarPath.getParentFile(). getAbsolutePath();" a "jarPath.getParent()". Funziona quindi come un fascino. – StackAddict

+0

Lo stesso è il problema nel mio caso, ma ho un progetto di base primavera. Come dire che il file è accanto al file jar? qualche idea – Mubasher

0

Ho un caso simile: volendo il mio file *.jar per accedere a un file in una directory accanto a detto file *.jar.Fare riferimento allo THIS ANSWER.

La mia struttura del file è:

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

sono in grado di caricare un file (ad esempio, some.txt) per un InputStream all'interno del file *.jar con il seguente:

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

Poi fare qualsiasi cosa con il stream