我有一个计划,将读到的一切从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"
它应该阅读全部来自四个属性config.properties
文件。 但是假设,如果我跑我的程序像这个 -
java -jar Test.jar "C:\\test\\config.properties" 10 100 2 TABLE1 TABLE2 TABLE3
那么它应该读从参数的所有属性和覆盖在config.properties文件的属性。
下面是我的代码,在此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
}
}
问题陈述:-
现在,我试图做的,如果任何人正在运行的程序这样的假设是 -
java -jar Test.jar "C:\\test\\config.properties" 10
然后在我的程序,它应该覆盖noOfThreads
only-
noOfThreads should be 10 instead of 100
再假设,如果该人正在运行的程序像这个 -
java -jar Test.jar "C:\\test\\config.properties" 10 100
然后在我的程序,它应该覆盖noOfThreads
和noOfTasks
only-
noOfThreads should be 10 instead of 100
noOfTasks should be 100 instead of 10000
和其他可能的使用情况也是如此。
任何人都可以建议我如何实现这一方案? 谢谢您的帮助
创建一个循环,来代替。
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
当定义的命令行输入如下
java -jar Test.jar "C:\\test\\config.properties" 10 100
这意味着人们必须始终提供noOfThreads
覆盖noOfTasks
。
为了解决这个问题,你可以指定它们作为命令行系统属性与其他明智都有一个默认的位置过于文件位置沿。 例如: -
java -jar -Dconfig.file.location="C:\\test\\config.properties" -DNUMBER_OF_THREADS=10 Test.jar
然后。
- 阅读文件属性为
Properties
。 - 遍历的属性键和查找与
System.getProperty()
- 如果值被发现属性覆盖相应的条目。
这样,不管你有多少新特性介绍你的代码将始终保持不变。
你可以走得更远一步,封装了所有的这一场PropertyUtil
还提供了实用的方法,如getIntProperty()
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");
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文件。