以下部分描述了有关如何在应用程序中使用 CLI 的一些示例场景。
布尔选项在命令行上由该选项的存在表示,即,如果找到该选项,则该选项值为真,否则该值为假。
DateApp实用程序将当前日期打印到标准输出。
如果存在-t选项,还会打印当前时间。
必须创建一个Options对象,并且必须将该选项添加到该对象中。
// create Options object Options options = new Options(); // add t option options.addOption("t", false, "display current time");
addOption 方法有三个参数。第一个参数用来指定选项,类型为 java.lang.String。第二个参数是一个布尔值,它指定选项是否需要参数。如果参数是布尔选项(有时也称为标志参数),布尔选项是不存在参数的,因此第二个参数设置为 false。第三个参数是选项的描述,此描述信息将在应用程序的使用文本中显示。
CommandLineParser 的解析方法用于解析命令行参数。CommandLineParser 接口可能有几种实现,建议使用 DefaultParser。
CommandLineParser parser = new DefaultParser(); CommandLine cmd = parser.parse(options, args);
现在我们需要检查是否存在 t 选项。为此,我们将询问 CommandLine 对象。hasOption 方法接受一个 java.lang.String 类型参数,如果存在由 java.lang.String 表示的选项,则返回 true,否则返回 false。
if(cmd.hasOption("t")) { // 打印日期和时间 } else { // 打印日期 }
注意:
从 1.5 版开始,DefaultParser 类提供了 DefaultParser(final boolean allowPartialMatching) 构造函数,它的 allowPartialMatching 参数用来开启/禁用部分匹配。如以下代码:
final Options options = new Options(); options.addOption(new Option("d", "debug", false, "Turn on debug.")); options.addOption(new Option("e", "extract", false, "Turn on extract.")); options.addOption(new Option("o", "option", true, "Turn on option with argument."));
如果开启了 “部分匹配” 后(即 allowPartialMatching=true),-de 参数只匹配 “debug” 选项。如果在禁用 “部分匹配” (即 allowPartialMatching=false)的情况下,-de 将同时启用调试(debug)和提取(extract)选项。
InternationalDateApp 实用程序通过提供打印世界上任何国家/地区的日期和时间的功能扩展了 DateApp 实用程序。为方便起见,引入了一个新的命令行选项 c。代码如下:
// add c option options.addOption("c", true, "country code");
第二个参数这次为 true。这里指定 c 选项需要一个参数值。如果在命令行上指定了必需的选项参数值,则返回该参数值。否则返回 null。
CommandLine 的 getOptionValue() 方法用于检索选项的参数值。代码如下:
// 获取 c 选项值 String countryCode = cmd.getOptionValue("c"); if(countryCode == null) { // 打印默认日期 } else { // 打印由国家代码指定的国家/地区的日期 }
这里将使用 Ant 来说明如何创建所需的选项,以下是Ant的帮助输出。
ant [options] [target [target2 [target3] ...]] Options: -help print this message -projecthelp print project help information -version print the version information and exit -quiet be extra quiet -verbose be extra verbose -debug print debugging information -emacs produce logging information without adornments -logfile <file> use given file for log -logger <classname> the class which is to perform logging -listener <classname> add an instance of class as a project listener -buildfile <file> use given buildfile -D<property>=<value> use value for given property -find <file> search for buildfile towards the root of the filesystem and use it
让我们为应用程序创建布尔选项,因为它们最容易创建。为清楚起见,此处使用了 Option 的构造函数。
Option help = new Option("help", "print this message"); Option projecthelp = new Option("projecthelp", "print project help information"); Option version = new Option("version", "print the version information and exit"); Option quiet = new Option("quiet", "be extra quiet"); Option verbose = new Option("verbose", "be extra verbose"); Option debug = new Option("debug", "print debugging information"); Option emacs = new Option("emacs", "produce logging information without adornments");
参数选项是使用 Option#Builder 创建的。
Option logfile = Option.builder("logfile") .argName("file") .hasArg() .desc("use given file for log") .build(); Option logger = Option.builder("logger") .argName("classname") .hasArg() .desc("the class which it to perform logging") .build(); Option listener = Option.builder("listener") .argName("classname") .hasArg() .desc("add an instance of class as " + "a project listener") .build(); Option buildfile = Option.builder("buildfile") .argName("file") .hasArg() .desc("use given buildfile") .build(); Option find = Option.builde("find") .argName("file") .hasArg() .desc("search for buildfile towards the " + "root of the filesystem and use it") .build();
要创建的最后一个选项是 Java 属性,它也是使用 OptionBuilder 创建的。
Option property = Option property = Option.builder("D") .hasArgs() .valueSeparator('=') .build();
稍后可以通过在 CommandLine 上调用 getOptionProperties("D") 方法来检索此选项指定的属性映射。
现在我们已经创建了每个选项,我们需要创建选项实例。这是使用 Options 的 addOption 方法实现的。
Options options = new Options(); options.addOption(help); options.addOption(projecthelp); options.addOption(version); options.addOption(quiet); options.addOption(verbose); options.addOption(debug); options.addOption(emacs); options.addOption(logfile); options.addOption(logger); options.addOption(listener); options.addOption(buildfile); options.addOption(find); options.addOption(property);
所有的准备工作现在已经完成,我们现在准备解析命令行参数。
我们现在需要创建一个 CommandLineParser。这将使用选项指定的规则解析命令行参数,并返回一个 CommandLine 实例。
public static void main(String[] args) { // create the parser CommandLineParser parser = new DefaultParser(); try { // parse the command line arguments CommandLine line = parser.parse(options, args); } catch (ParseException exp) { // oops, something went wrong System.err.println("Parsing failed. Reason: " + exp.getMessage()); } }
要查看是否已传递选项,请使用 hasOption 方法。可以使用 getOptionValue 方法检索参数值。
// 是否指定了 buildfile 参数? if(line.hasOption("buildfile")) { // initialise the member variable this.buildfile = line.getOptionValue("buildfile"); }
CLI 还提供了自动生成使用和帮助信息的方法。这是通过 HelpFormatter 类实现的。
// 自动生成帮助说明 HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("ant", options);
执行时会产生以下输出:
usage: ant -D <property=value> use value for given property -buildfile <file> use given buildfile -debug print debugging information -emacs produce logging information without adornments -file <file> search for buildfile towards the root of the filesystem and use it -help print this message -listener <classname> add an instance of class as a project listener -logger <classname> the class which it to perform logging -projecthelp print project help information -quiet be extra quiet -verbose be extra verbose -version print the version information and exit
如果您还需要打印使用说明,则调用 formatter.printHelp("ant", options, true) 将生成使用说明以及帮助信息。
Linux/Unix 世界中使用最广泛的命令行应用程序之一是 ls。由于 ls 需要大量选项,本示例仅涵盖一小部分选项。以下是输出的一部分帮助信息:
Usage: ls [OPTION]... [FILE]... List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuSUX nor --sort. -a, --all do not hide entries starting with . -A, --almost-all do not list implied . and .. -b, --escape print octal escapes for non-graphic characters --block-size=SIZE use SIZE-byte blocks -B, --ignore-backups do not list implied entries ending with ~ -c with -lt: sort by, and show, ctime (time of last modification of file status information) with -l: show ctime and sort by name otherwise: sort by ctime -C list entries by columns
以下是用于为此示例创建选项的代码:
// 创建命令行解析器 CommandLineParser parser = new DefaultParser(); // 创建 Options Options options = new Options(); options.addOption("a", "all", false, "do not hide entries starting with ."); options.addOption("A", "almost-all", false, "do not list implied . and .."); options.addOption("b", "escape", false, "print octal escapes for non-graphic " + "characters"); options.addOption(Option.builder("SIZE").longOpt("block-size") .desc("use SIZE-byte blocks") .hasArg() .build()); options.addOption("B", "ignore-backups", false, "do not list implied entries " + "ending with ~"); options.addOption("c", false, "with -lt: sort by, and show, ctime (time of last " + "modification of file status information) with " + "-l:show ctime and sort by name otherwise: sort " + "by ctime"); options.addOption("C", false, "list entries by columns"); String[] args = new String[]{ "--block-size=10" }; try { // 解析命令行参数 CommandLine line = parser.parse(options, args); // 验证是否设置了 block-size 选项 if (line.hasOption("block-size")) { // 打印 block-size 选项的值 System.out.println(line.getOptionValue("block-size")); } } catch (ParseException exp) { System.out.println("Unexpected exception:" + exp.getMessage()); }