如何在Java中解析命令行参数?

How do I parse command line arguments in Java?

在Java中解析命令行参数的好方法是什么?


检查这些出来:

  • http:/ / / / cli commons.apache.org
  • http:/ / / / jsap www.martiansoftware.com

或你自己:卷

  • docs.oracle.com http:/ / / / / / 7 javase Java API文档scanner.html util / / /

例如,这是你如何使用commons-cli弦乐支持两大解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import org.apache.commons.cli.*;

public class Main {


    public static void main(String[] args) throws Exception {

        Options options = new Options();

        Option input = new Option("i","input", true,"input file path");
        input.setRequired(true);
        options.addOption(input);

        Option output = new Option("o","output", true,"output file");
        output.setRequired(true);
        options.addOption(output);

        CommandLineParser parser = new DefaultParser();
        HelpFormatter formatter = new HelpFormatter();
        CommandLine cmd;

        try {
            cmd = parser.parse(options, args);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            formatter.printHelp("utility-name", options);

            System.exit(1);
        }

        String inputFilePath = cmd.getOptionValue("input");
        String outputFilePath = cmd.getOptionValue("output");

        System.out.println(inputFilePath);
        System.out.println(outputFilePath);

    }

}

从命令行用法:

1
2
3
4
5
6
$> java -jar target/my-utility.jar -i asd                                                                                      
Missing required option: o

usage: utility-name
 -i,--input     input file path
 -o,--output    output file


把一个看起来在最近的jcommander更多。

我创造了它。我是快乐的receive问题或要求大的特征。


我已试图维持一个列表的cli parsers Java。

  • 包机
    • 叉:积极github.com HTTPS:/ / / rvesse包机
  • argparse4j
  • argparser
  • args4j
  • clajr
  • cli -语法分析器
  • cmdln
  • commandline
  • docopt.java
  • getopt海豚
  • dpml cli(雅加达commons cli2叉)
  • 马蒂亚斯laux博士。
  • 雅加达commons cli
  • jargo
  • jargp
  • jargs
  • - getopt Java
  • jbock
  • jclap
  • jcmdline
  • jcommander
  • jcommando
  • jewelcli(由我写的)
  • jopt简单
  • jsap
  • naturalcli
  • 面向对象cli导师的文章(更多关于refactoring和tdd)
  • - cmd解析
  • ritopt
  • rop
  • TE -代码命令
  • picocli已colorized用法的帮助和autocomplete信号


我已经使用并发现它相当的jopt:HTTP:/ / jopt-simple.sourceforge.net /

还提供了一个列表的前页的关于他们的另类图书馆8,检查出来的人是最的服,拿起你的需要。


我最近有人指出这是基于args4j标注。我喜欢它!


买还是建?

许多像应用程序这样的小实用程序可能会滚动自己的命令行解析,以避免额外的外部依赖。

皮科利可能很有趣。它被设计成作为源代码,作为一种简单的替代方法,而不是将jar隐藏到uberjar中。

您可能喜欢的另一个功能是它的彩色用法帮助。

Minimal usage help with ANSI colors

分析器功能:

  • 基于注释:解析是一行代码
  • 强类型的所有内容-命令行选项和位置参数
  • posix簇状短期权( -xvfInputFile -x -v -f InputFile)
  • 一种arity模型,允许最小、最大和可变数量的参数,如"1..*""3..5"
  • 子命令(可以嵌套到任意深度)
  • 使用Java 5和更高的工作

使用帮助消息很容易通过注释进行自定义(无需编程)。例如:

Extended usage help message(来源)

我忍不住再添加一个屏幕截图来显示哪些使用帮助消息是可能的。使用帮助是你的应用程序的正面,所以要有创意,玩得开心!

picocli demo

免责声明:我创建了Picocli。欢迎反馈或提问。


这是谷歌的指挥线parsing图书馆开放sourced作为bazel部分项目。我认为它的personally最好有一个远比cli容易,和Apache。

HTTPS:/ / / / github.com pcj谷歌-选项

安装 bazel

1
2
3
4
5
maven_jar(
    name ="com_github_pcj_google_options",
    artifact ="com.github.pcj:google-options:jar:1.0.0",
    sha1 ="85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)

gradle

1
2
3
dependencies {
  compile 'com.github.pcj:google-options:1.0.0'
}

maven

1
2
3
4
5
<dependency>
  <groupId>com.github.pcj</groupId>
  google-options</artifactId>
  <version>1.0.0</version>
</dependency>

使用

创建一个类的定义,扩展OptionsBase@Option(S)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package example;

import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;

import java.util.List;

/**
 * Command-line options definition for example server.
 */

public class ServerOptions extends OptionsBase {

  @Option(
      name ="help",
      abbrev = 'h',
      help ="Prints usage info.",
      defaultValue ="true"
    )
  public boolean help;

  @Option(
      name ="host",
      abbrev = 'o',
      help ="The server host.",
      category ="startup",
      defaultValue =""
  )
  public String host;

  @Option(
    name ="port",
    abbrev = 'p',
    help ="The server port.",
    category ="startup",
    defaultValue ="8080"
    )
    public int port;

  @Option(
    name ="dir",
    abbrev = 'd',
    help ="Name of directory to serve static files.",
    category ="startup",
    allowMultiple = true,
    defaultValue =""
    )
    public List<String> dirs;

}

解析的支持和使用他们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package example;

import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;

public class Server {

  public static void main(String[] args) {
    OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
    parser.parseAndExitUponError(args);
    ServerOptions options = parser.getOptions(ServerOptions.class);
    if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
      printUsage(parser);
      return;
    }

    System.out.format("Starting server at %s:%d...
"
, options.host, options.port);
    for (String dirname : options.dirs) {
      System.out.format("\\--> Serving static files at <%s>
"
, dirname);
    }
  }

  private static void printUsage(OptionsParser parser) {
    System.out.println("Usage: java -jar server.jar OPTIONS");
    System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
                                              OptionsParser.HelpVerbosity.LONG));
  }

}

HTTPS:/ / / / github.com pcj谷歌-选项


把一个项目的commons cli看看,很多好的东西在那里。


yeap。

我认为你要找什么,像这样: HTTP:/ / commons.apache.org / cli

The Apache Commons CLI library provides an API for processing command line interfaces.


也许这些

  • 请选择parsing jargs指挥线 为Java套件-这小小的项目提供了一个紧凑的,convenient,预packaged和comprehensively documented套件的指挥线parsers请选择为使用的Java程序员。initially,parsing compatible GNU风格"与"getopt -是提供。

  • ritopt期权,最终为Java语法分析器-虽然一些命令,请选择标准的航运已preposed,ritopt如下的conventions prescribed在opt包。


你能找到这篇文章的unhappiness元作为一个跳跃点有趣的地方:

http:/ / / / / command-line-parsing-libraries-for-java.html 2008年07 furiouspurpose.blogspot.com


我写另一个argparse4j.sourceforge.net:HTTP:/ / /

argparse4j是一个指挥线argument图书馆为Java的语法分析器,基于Python的argparse。


如果你是熟悉与Java的GNU getopt,有一个在港:HTTP:/ / / / / download.htm www.urbanophile.com arenn黑客。

有似乎是一个类,这一些原因:

  • HTTP:/ / docs.sun.com /源/ 5618 816年- 10 / / / / getopt.html util Netscape LDAP
  • HTTP:/ / xml.apache.org xalan - J / / / / / xalan Apache apidocs org / / / / getopt.html xsltc cmdline getopt

github包机"看起来很好。它是基于标注,是想试图模仿git指挥线结构。


我知道这里的大多数人都会找到1000万个不喜欢我的理由,但永远不会。我喜欢保持简单,所以我只需使用"="将键与值分开,并将它们存储在哈希图中,如下所示:

1
2
3
4
5
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
    String[] parts = arg.split("=");
    argsMap.put(parts[0], parts[1]);
}

您可以一直用您期望的参数维护一个列表,以帮助用户避免忘记参数或使用了错误的参数…但是,如果您想要太多的功能,这个解决方案无论如何都不适合您。


我不会recommend Apache使用常见的cli图书馆,因为它是非threadsafe。 它使用静态方法和类与stateful variables做内部的工作(例如optionbuilder)和应该只用于在单threaded强烈的受控情况。


如果您想要一些轻量级的(JAR大小约20KB)和简单易用的东西,可以尝试使用参数解析器。它可以在大多数用例中使用,支持在参数中指定数组,并且不依赖于任何其他库。它适用于Java 1.5或以上。下面的摘录显示了一个如何使用它的示例:

1
2
3
4
5
6
7
8
public static void main(String[] args) {
    String usage ="--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
    ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
    InputData inputData = (InputData) argParser.parse(args);
    showData(inputData);

    new StatsGenerator().generateStats(inputData);
}

这里有更多的例子


argparse4j是我找到的最好的。它模仿了python的argparse库,非常方便和强大。


正如前面提到的其中一条评论(https://github.com/pcj/google-options)将是一个很好的选择。

我想添加的一件事是:

1)如果遇到分析器反射错误,请尝试使用较新版本的guava。在我看来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
maven_jar(
    name ="com_google_guava_guava",
    artifact ="com.google.guava:guava:19.0",
    server ="maven2_server",
)

maven_jar(
    name ="com_github_pcj_google_options",
    artifact ="com.github.pcj:google-options:jar:1.0.0",
    server ="maven2_server",
)

maven_server(
    name ="maven2_server",
    url ="http://central.maven.org/maven2/",
)

2)运行命令行时:

1
bazel run path/to/your:project -- --var1 something --var2 something -v something

3)需要使用帮助时,只需键入:

1
bazel run path/to/your:project -- --help


对于Spring用户,我们还应该提到https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/simplecommandlinepropertysource.html和他的孪生兄弟https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/joptcommandlinepropertysource.html(相同功能的jopt实现)Spring的优点是可以直接将命令行参数绑定到属性,这里有一个示例:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/commandlinepropertysource.html