2013-03-18 60 views
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"

它应全部来自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

然后在我的程序,它应该覆盖noOfThreadsnoOfTasks only-

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

还有可能的其他用例。

任何人都可以建议我如何实现这一方案?感谢您的帮助

回答

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 
+0

ASK Adeel。感谢Adeel的帮助。我不使用JDK1.7,因此不能使用这些大括号。 :(而且还可以提供你我的全部流程在那里我应该把这个做这件事的工作感谢您的帮助 – ferhan 2013-03-18 04:10:45

+0

TechGeeky:我已经取代钻石商,这样你就可以使用Java 6 – 2013-03-19 01:49:51

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文件。

7

当定义如下

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

然后。

  1. 将文件属性读入Properties
  2. 迭代属性中的键并找到相应的System.getProperty()
  3. 如果找到值,则覆盖属性中的相应条目。

这样无论你介绍多少新属性你的代码都会保持不变。

你可以走得更远一步,封装了所有的这一场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"); 
+0

由于使用sgp15的意见。如果你能提供给我对我的情况为例基础,然后我就可以了解好多了。感谢您的帮助。 – ferhan 2013-03-18 04:12:31

+0

@TechGeeky。你去那里。 – sgp15 2013-03-18 04:23:49

+0

+1 -D单独的选择。顺便说一句,你的getIntProperty()似乎坏了,所以我修正了它,如果你认为它确实是正确的,那么欢迎你回复它。 – 2013-03-18 06:16:32