2013-03-18 6 views
5

Ho un programma che leggerà tutto dal file config.properties se la riga di comando non contiene alcun argomento oltre alla posizione del file config.properties. Sotto è il mio config.properties File-Sovrascrive il file delle proprietà se è presente il valore della riga di comando

NUMBER_OF_THREADS: 100 
NUMBER_OF_TASKS: 10000 
ID_START_RANGE: 1 
TABLES: TABLE1,TABLE2 

Se sto facendo funzionare il mio programma dal prompt dei comandi come questo-

java -jar Test.jar "C:\\test\\config.properties"

Dovrebbe leggere tutti i quattro oggetti di file config.properties. Ma supponiamo che se sto facendo funzionare il mio programma come questo-

java -jar Test.jar "C:\\test\\config.properties" 10 100 2 TABLE1 TABLE2 TABLE3

allora dovrebbe leggere tutte le proprietà dagli argomenti e sovrascrivere le proprietà nel file config.properties.

Qui di seguito è il mio codice che sta funzionando benissimo in questo scenario-

public static void main(String[] args) { 

     try { 

      readPropertyFiles(args); 

     } catch (Exception e) { 
      LOG.error("Threw a Exception in" + CNAME + e); 
     } 
    } 

    private static void readPropertyFiles(String[] args) throws FileNotFoundException, IOException { 

     location = args[0]; 

     prop.load(new FileInputStream(location)); 

     if(args.length >= 1) { 
      noOfThreads = Integer.parseInt(args[1]); 
      noOfTasks = Integer.parseInt(args[2]); 
      startRange = Integer.parseInt(args[3]); 

      tableName = new String[args.length - 4]; 
      for (int i = 0; i < tableName.length; i++) { 
       tableName[i] = args[i + 4]; 
       tableNames.add(tableName[i]); 
      } 
     } else { 
      noOfThreads = Integer.parseInt(prop.getProperty("NUMBER_OF_THREADS").trim()); 
      noOfTasks = Integer.parseInt(prop.getProperty("NUMBER_OF_TASKS").trim()); 
      startRange = Integer.parseInt(prop.getProperty("ID_START_RANGE").trim()); 
      tableNames = Arrays.asList(prop.getProperty("TABLES").trim().split(",")); 
     } 

     for (String arg : tableNames) { 

      //Some Other Code 

     } 
    } 

problema dichiarazione: -

Ora quello che sto cercando di fare è-Supponiamo che se una persona è in esecuzione programma come questo

java -jar Test.jar "C:\\test\\config.properties" 10

poi nel mio programma, dovrebbe sovrascrivere 01.235.solo-

noOfThreads should be 10 instead of 100 

E supponiamo se quella persona è in esecuzione programma come questo-

java -jar Test.jar "C:\\test\\config.properties" 10 100

poi nel mio programma, dovrebbe sovrascrivere noOfThreads e noOfTasks solo-

noOfThreads should be 10 instead of 100 
noOfTasks should be 100 instead of 10000 

E possibili altri casi d'uso.

Qualcuno può suggerirmi come raggiungere questo scenario? Grazie per l'aiuto

risposta

2

Creare un ciclo, invece.

List<String> paramNames = new ArrayList<String>{"NUMBER_OF_THREADS", "NUMBER_OF_TASKS", 
      "ID_START_RANGE", "TABLES"}; // Try to reuse the names from the property file 
Map<String, String> paramMap = new HashMap<String, String>(); 
... 
// Validate the length of args here 
... 
// As you table names can be passed separately. You need to handle that somehow. 
// This implementation would work when number of args will be equal to number of param names 
for(int i = 0; i< args.length; i++) { 
    paramMap.put(paramNames[i], args[i]); 
} 

props.putAll(paramMap); 
... // Here props should have it's values overridden with the ones provided 
+0

ASK Adeel. Grazie Adeel per l'aiuto. Non sto usando JDK1.7 quindi non posso usare quelle parentesi. :(E inoltre puoi fornirmi il flusso completo dove dovrei mettere questo per far funzionare questa cosa.Grazie per l'aiuto – ferhan

+0

TechGeeky: Ho sostituito gli operatori di diamante, quindi puoi usarlo con Java 6. –

0
Properties properties = new Properties(); 
properties.load(new FileInputStream("C:\\test\\config.properties")); 

Quindi secondo i vostri argomenti della riga di comando impostare le singole proprietà come:

setProperty("NUMBER_OF_THREADS", args[1]); 
setProperty("NUMBER_OF_TASKS", args[2]); 

questo non cancella il file config.properties esistente.

7

Quando si definisce ingresso della linea di comando come segue

java -jar Test.jar "C:\\test\\config.properties" 10 100

Significa bisogna sempre fornire noOfThreads ignorare noOfTasks.

Per risolvere questo problema, è possibile specificare queste proprietà di sistema sulla riga di comando insieme alla posizione del file, che in altri casi ha anche una posizione predefinita. Ad esempio: -

java -jar -Dconfig.file.location="C:\\test\\config.properties" -DNUMBER_OF_THREADS=10 Test.jar

Poi.

  1. Leggere le proprietà del file in Properties.
  2. Iterare sui tasti nelle proprietà e trovare System.getProperty() corrispondente.
  3. Se viene trovato un valore, sostituisce la voce corrispondente nelle proprietà.

In questo modo non importa quante nuove proprietà introduci il tuo codice rimarrà sempre uguale.

si può andare oltre e incapsulare tutto questo in un PropertyUtil che forniscono anche i metodi di utilità come getIntProperty(), getStringProperty() ecc

import java.io.FileInputStream; 
import java.io.IOException; 
import java.util.Properties; 

public class PropertyUtil { 

    private static final String DEFAULT_CONFIG_FILE_LOCATION = "config.properties"; 

    private String configFileLocation; 

    private Properties properties; 

    public PropertyUtil() throws IOException { 

    this(DEFAULT_CONFIG_FILE_LOCATION); 
    } 

    public PropertyUtil(String configFileLocation) throws IOException { 

    this.configFileLocation = configFileLocation; 
    this.properties = new Properties(); 
    init(); 
    } 

    private void init() throws IOException { 

    properties.load(new FileInputStream(this.configFileLocation)); 

    for (Object key : this.properties.keySet()) { 

     String override = System.getProperty((String) key); 

     if (override != null) { 

     properties.put(key, override); 
     } 
    } 
    } 

    public int getIntProperty(String key) { 

    return this.properties.contains(key) ? Integer.parseInt(properties.get(key)) : null; 
    } 

    public String getStringProperty(String key) { 

    return (String) this.properties.get(key); 
    } 
} 

Esempi.

config.properties

NUMBER_OF_THREADS=100 
NUMBER_OF_TASKS=10000 
ID_START_RANGE=1 
TABLES=TABLE1,TABLE2 

di ignorare NUMBER_OF_THREADS.

java -jar -Dconfig.file.location="C:\\test\\config.properties" -DNUMBER_OF_THREADS=10 Test.jar

esempio mano corta per leggere 'NUMBER_OF_THREADS' come int.

new PropertyUtil(System.getProperty("config.file.location")).getIntProperty("NUMBER_OF_THREADS"); 
+0

Grazie sgp15 per il suggerimento Se potessi fornirmi una base esemplificativa sul mio scenario, sarei in grado di capire molto meglio Grazie per l'aiuto – ferhan

+0

@ TechGeeky. Ci vai. – sgp15

+0

+1 per opzione -D da solo. la tua getIntProperty() sembra rotta, quindi ho risolto il problema, puoi ripristinarlo se ritieni che sia effettivamente corretto. –