5

config.propertiesコマンドラインにconfig.propertiesファイルの場所以外の引数が含まれていない場合、ファイルからすべてを読み取るプログラムがあります。以下は私のconfig.propertiesファイルです-

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

このようにコマンドプロンプトからプログラムを実行している場合-

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

ファイルから 4 つのプロパティをすべて読み取る必要がありconfig.propertiesます。しかし、このようにプログラムを実行しているとします-

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

次に、引数からすべてのプロパティを読み取り、config.properties ファイル内のプロパティを上書きする必要があります。

以下は、このシナリオで正常に動作している私のコードです-

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

        }
    }   

問題文:-

今私がやろうとしていることは、誰かがこのようなプログラムを実行しているとします

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

noOfThreads次に、私のプログラムでは、上書きする必要があります-

noOfThreads should be 10 instead of 100

そして、その人がこのようなプログラムを実行しているとします-

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

次に、私のプログラムでは、上書きする必要がありますnoOfThreads-noOfTasks

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

また、他のユースケースも考えられます。

このシナリオを達成する方法を誰かに提案できますか? 助けてくれてありがとう

4

3 に答える 3

8

コマンドライン入力を次のように定義する場合

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

noOfThreadsこれは常にoverrideを提供しなければならないことを意味しますnoOfTasks

これを解決するには、コマンド ラインでこれらをシステム プロパティとして指定し、ファイルの場所も指定します。ファイルの場所にはデフォルトの場所もあります。例えば: -

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

それで。

  1. ファイル プロパティを に読み込みますProperties
  2. プロパティのキーを反復処理し、対応する を見つけますSystem.getProperty()
  3. 値が見つかった場合は、プロパティの対応するエントリをオーバーライドします。

このように、いくつの新しいプロパティを導入しても、コードは常に同じままです。

さらに一歩進んで、これらすべてを などのユーティリティ メソッドも提供する にカプセル化することができますPropertyUtilgetIntProperty()getStringProperty()

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

例。

config.properties

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

をオーバーライドしますNUMBER_OF_THREADS

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

「NUMBER_OF_THREADS」を int として読み取る簡単な例。

new PropertyUtil(System.getProperty("config.file.location")).getIntProperty("NUMBER_OF_THREADS");
于 2013-03-18T04:11:08.463 に答える
2

代わりに、ループを作成してください。

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
于 2013-03-18T04:07:47.853 に答える
0
Properties properties = new Properties();
properties.load(new FileInputStream("C:\\test\\config.properties"));

次に、コマンドライン引数に従って、個々のプロパティを次のように設定します。

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

これにより、既存の config.properties ファイルが上書きされることはありません。

于 2013-03-18T04:06:27.887 に答える