1.Commons CLI
Apache Commons CLI提供瞭解析命令行參數的API。它也可以在命令行打印詳細的參數信息。官網教程:http://commons.apache.org/proper/commons-cli/usage.html,Commons CLI的Javadoc:http://commons.apache.org/proper/commons-cli/javadocs/api-release/index.html。
Commons CLI提供了一下不同類型的參數形式
- POSIX(Portable Operating System Interface of Unix)形式,如:tar -zxvf foo.tar.gz
- GNU中長參數形式,如:du --human-readable --max-depth=1
- Java命令中的參數形式,如:java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo
- 短槓帶參數值的形式,如:gcc -O2 foo.c
- 長槓不帶參數值的形式,如:ant – projecthelp
2.CLI定義階段
Apache Commons CLI使用Options這個類來定義和設置參數,它是所有參數的容器。它提供了下面幾種方法添加參數:
addOption(Option opt)
addOption(String opt, boolean hasArg, String description)
addOption(String opt, String description)
addOption(String opt, String longOpt, boolean hasArg, String description)
第二和第三個方法用於添加短名稱(或名稱縮寫)參數,第四個方法還提供了長名稱參數。而其中的boolean參數爲true時,當調用getOptionValue()方法時,可以返回對應的參數只;反之,爲false時,返回null。
其中,第一個方法要更復雜些。需要先創建一個Option對象,Option對象是由OptionBuilder創建的。如:
Option filesOption = OptionBuilder.withArgName("args")
.withLongOpt("files")
.hasArgs(2)
.withValueSeparator(',')
.withDescription("file names")
.create("f");
hasArgs()方法指定參數後有幾個值,withValueSeparator(char seq)指定參數值之間的分隔符。
3.CLI解析階段
在解析階段中,通過命令行傳入應用程序的文本來進行處理。處理過程將根據在解析器的實現過程中定義的規則來進行。Commons CLI提供了一個接口CommandLineParser,而且分別實現了下面幾種解析器,用於不同的場景:
- DefaultParser:提供了很基礎的解析功能,只能解析基礎的命令行參數。
- BasicParser:提供了基礎的解析功能,能解析簡單的命令行參數。
- PosixParser:提供瞭解析POSIX形式參數的功能。
- GnuParser:提供瞭解析長參數及Java命令中參數的功能。
CommandLineParser parser = new PosixParser();
CommandLine cli = parser.parse(options, args);
4.CLI詢問階段
在詢問階段中,應用程序通過查詢 CommandLine,並通過其中的布爾參數和提供給應用程序的參數值來決定需要執行哪些程序分支。這個階段在用戶的代碼中實現,CommandLine 中的訪問方法爲用戶代碼提供了 CLI 的詢問能力。
CLI 詢問階段的目標結果就是將所有通過命令行以及處理參數過程中得到的文本信息傳遞給用戶的代碼。
if(cli.hasOption("h")){
HelpFormatter hf = new HelpFormatter();
hf.printHelp("Options", options);
}
5.CLI使用
5.1CLI配置
要使用Commons CLI需要將其JAR加入到CLASSPATH,或者如下添加Maven依賴:
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>${cli-version}</version>
</dependency>
5.2Basic Parser
BasicParser和DefaultParser只能解析基礎的命令行參數,如:
public static void basicParseCLI(String[] args){
Options options = new Options();
options.addOption("h", "help", false, "print options' information");
options.addOption("d", "database", true, "name of a database");
options.addOption("t", true, "name of a table");
Option filesOption = OptionBuilder.withArgName("args")
.withLongOpt("files")
.hasArgs()
.withDescription("file names")
.create("f");
options.addOption(filesOption);
// CommandLineParser parser = new DefaultParser();
CommandLineParser parser = new BasicParser();
try {
CommandLine cli = parser.parse(options, args);
if(cli.hasOption("h")){
HelpFormatter hf = new HelpFormatter();
hf.printHelp("Options", options);
}
else {
String database = cli.getOptionValue("d");
System.out.println("database: " + database);
String table = cli.getOptionValue("t");
System.out.println("table: " + table);
String[] files = cli.getOptionValues("f");
System.out.println("files: " + Arrays.asList(files));
}
}
catch (Exception e){
e.printStackTrace();
}
}
命令行參數:
-d database -t table -files file1 file2
-database database -t table -files file1 file2
輸出:
database: database
table: table
files: [file1, file2]
5.3POSIX Parser
PosixParser可以解析POSIX形式的命令行參數和Java命令中參數形式,如:
public static void posixParseCLI(String[] args){
Options options = new Options();
options.addOption("h", "help", false, "print options' information");
options.addOption("d", "database", true, "name of a database");
options.addOption("t", true, "name of a table");
Option filesOption = OptionBuilder.withArgName("args")
.withLongOpt("files")
.hasArgs()
.withDescription("file names")
.create("f");
options.addOption(filesOption);
// hasArgs()指定後跟參數值得個數
Option property = OptionBuilder.withArgName("property=name")
.hasArgs()
.withValueSeparator()
.withDescription("use value for a property")
.create("D");
options.addOption(property);
CommandLineParser parser = new PosixParser();
try {
CommandLine cli = parser.parse(options, args);
if(cli.hasOption("h")){
HelpFormatter hf = new HelpFormatter();
hf.printHelp("Options", options);
}
else {
String database = cli.getOptionValue("d");
System.out.println("database: " + database);
String table = cli.getOptionValue("t");
System.out.println("table: " + table);
String[] files = cli.getOptionValues("f");
System.out.println("files: " + Arrays.asList(files));
Properties properties = cli.getOptionProperties("D");
String ext = properties.getProperty("ext");
System.out.println("property ext = " + ext);
}
}
catch (Exception e){
e.printStackTrace();
}
}
命令行參數:
-d database -ttable -files file1 file2 -Dext=java
輸出:
database: database
table: table
files: [file1, file2]
property ext = java
5.4GNU Parser
GnuParser可以解析長參數及Java命令中參數,如:opt=value。
public static void gnuParseCLI(String[] args){
Options options = new Options();
options.addOption("h", "help", false, "print options' information");
options.addOption("d", "database", true, "name of a database");
options.addOption("t", true, "name of a table");
// withValueSeparator(char sep)指定參數值之間的分隔符
Option filesOption = OptionBuilder.withArgName("args")
.withLongOpt("files")
.hasArgs()
.withValueSeparator(',')
.withDescription("file names")
.create("f");
options.addOption(filesOption);
Option property = OptionBuilder.withArgName("property=name")
.hasArgs()
.withValueSeparator()
.withDescription("use value for a property")
.create("D");
options.addOption(property);
CommandLineParser parser = new GnuParser();
try {
CommandLine cli = parser.parse(options, args);
if(cli.hasOption("h")){
HelpFormatter hf = new HelpFormatter();
hf.printHelp("Options", options);
}
else {
String database = cli.getOptionValue("database");
System.out.println("database: " + database);
String table = cli.getOptionValue("t");
System.out.println("table: " + table);
String[] files = cli.getOptionValues("f");
System.out.println("files: " + Arrays.asList(files));
Properties properties = cli.getOptionProperties("D");
String ext = properties.getProperty("ext");
String dir = properties.getProperty("dir");
System.out.println("property ext: " + ext + "\tdir:" + dir);
}
}
catch (Exception e){
e.printStackTrace();
}
}
命令行參數:
--database=database -t table --files=file1,file2 -Dext=java -Ddir=dir
輸出:
database: database
table: table
files: [file1, file2]
property ext: java dir:dir