Common CLI

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提供了一下不同类型的参数形式

  1. POSIX(Portable Operating System Interface of Unix)形式,如:tar -zxvf foo.tar.gz
  2. GNU中长参数形式,如:du --human-readable --max-depth=1
  3. Java命令中的参数形式,如:java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo
  4. 短杠带参数值的形式,如:gcc -O2 foo.c
  5. 长杠不带参数值的形式,如: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,而且分别实现了下面几种解析器,用于不同的场景:
  1. DefaultParser:提供了很基础的解析功能,只能解析基础的命令行参数。
  2. BasicParser:提供了基础的解析功能,能解析简单的命令行参数。
  3. PosixParser:提供了解析POSIX形式参数的功能。
  4. 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



你可能感兴趣的:(java,cli,commons-cli)