当前位置:首页 > 科技  > 软件

怎么基于Java编写一个CLI工具?

来源: 责编: 时间:2023-12-11 09:26:18 277观看
导读CLICLI,全称为命令行界面(Command Line Interface),是一种用于通过键盘输入指令与操作系统进行交互的软件机制。这种界面是在图形用户界面得到普及之前使用最为广泛的用户界面,并且, 即使在当前图形用户界面广泛使用的环境

CLI

CLI,全称为命令行界面(Command Line Interface),是一种用于通过键盘输入指令与操作系统进行交互的软件机制。这种界面是在图形用户界面得到普及之前使用最为广泛的用户界面,并且, 即使在当前图形用户界面广泛使用的环境下,CLI仍然有其独特的优势和广泛的应用。Psj28资讯网——每日最新资讯28at.com

对于CLI,它的一个重要特性就是效率。用户可以在一条文本命令中对多个文件执行操作,而不需要在各个窗口之间切换,节省了大量时间。此外,如果你已经熟悉了这些命令,那么你可以非常快速地浏览系统并与之交互。Psj28资讯网——每日最新资讯28at.com

构建CLI的工具很多,今天主要基于Java语言来实现,其中Apache Commons CLI框架提供了这样的便利。今天结合之前学习的graalVM提供的native-image工具,来生成一个exe类型的可执行文件,由于graalVM的跨平台性,我们还能生成各个平台的CLI命令来辅助完成更多的工作。Psj28资讯网——每日最新资讯28at.com

Apache Commons CLI是一个用于编写命令行界面的Java库。它提供了一个灵活的框架,可以很容易地定义和解析命令行参数。这个库的主要优点是它可以处理各种类型的参数,包括选项、位置参数、可选参数等。Psj28资讯网——每日最新资讯28at.com

构成

下面以native-image为例,通过在终端输入native-image --help可以看到以下信息Psj28资讯网——每日最新资讯28at.com

_> native-image --helpGraalVM Native Image (https://www.graalvm.org/native-image/)This tool can ahead-of-time compile Java code to native executables.Usage: native-image [options] class [imagename] [options]           (to build an image for a class)   or  native-image [options] -jar jarfile [imagename] [options]           (to build an image for a jar file)   or  native-image [options] -m <module>[/<mainclass>] [options]       native-image [options] --module <module>[/<mainclass>] [options]           (to build an image for a module)where options include:    @argument files       one or more argument files containing options    -cp <class search path of directories and zip/jar files>    -classpath <class search path of directories and zip/jar files>    --class-path <class search path of directories and zip/jar files>                          A ; separated list of directories, JAR archives,                          and ZIP archives to search for class files.    -p <module path>    --module-path <module path>...                          A ; separated list of directories, each directory                          is a directory of modules.

一个合格的CLI基本都会提供help选项来展示,这个CLI的语法、选项以及功能描述。从上面的输出可以看到help主要包括:Psj28资讯网——每日最新资讯28at.com

  1. 介绍:主要对命令的功能的描述,包括官网、版本以及一些内在系数等
  2. 用法:包括命令语法格式、配置项、参数等信息
  3. 参数说明:具体配置项参数的说明,以及具体的功能描述

Common-CLI

  • 定义阶段:在Java代码中定义Option参数,定义参数、是否需要输入值、简单的描述等
  • 解析阶段:应用程序传入参数后,CLI进行解析
  • 询问阶段:通过查询CommandLine询问进入到哪个程序分支中

定义阶段

主要是借助Option类提供的API来构建各种选项以及参数信息,下面是对应API的描述:Psj28资讯网——每日最新资讯28at.com

返回值Psj28资讯网——每日最新资讯28at.com

方法名Psj28资讯网——每日最新资讯28at.com

说明Psj28资讯网——每日最新资讯28at.com

OptionsPsj28资讯网——每日最新资讯28at.com

addOption(Option opt)Psj28资讯网——每日最新资讯28at.com

添加一个选项实例Psj28资讯网——每日最新资讯28at.com

OptionsPsj28资讯网——每日最新资讯28at.com

addOption(String opt, boolean hasArg, String description)Psj28资讯网——每日最新资讯28at.com

添加一个只包含短名称的选项Psj28资讯网——每日最新资讯28at.com

OptionsPsj28资讯网——每日最新资讯28at.com

addOption(String opt, String description)Psj28资讯网——每日最新资讯28at.com

添加一个只包含短名称的选项Psj28资讯网——每日最新资讯28at.com

OptionsPsj28资讯网——每日最新资讯28at.com

addOption(String opt, String longOpt, boolean hasArg, String description)Psj28资讯网——每日最新资讯28at.com

添加一个包含短名称和长名称的选项Psj28资讯网——每日最新资讯28at.com

OptionsPsj28资讯网——每日最新资讯28at.com

addOptionGroup(OptionGroup group)Psj28资讯网——每日最新资讯28at.com

添加一个选项组Psj28资讯网——每日最新资讯28at.com

ListPsj28资讯网——每日最新资讯28at.com

getMatchingOptions(String opt)Psj28资讯网——每日最新资讯28at.com

获得匹配选项的长名称集合Psj28资讯网——每日最新资讯28at.com

OptionPsj28资讯网——每日最新资讯28at.com

getOption(String opt)Psj28资讯网——每日最新资讯28at.com

通过长名称或短名称获得选项Psj28资讯网——每日最新资讯28at.com

OptionGroupPsj28资讯网——每日最新资讯28at.com

getOptionGroup(Option opt)Psj28资讯网——每日最新资讯28at.com

获得选项所在的选项组Psj28资讯网——每日最新资讯28at.com

CollectionPsj28资讯网——每日最新资讯28at.com

getOptions()Psj28资讯网——每日最新资讯28at.com

获得一个只读的选项集合Psj28资讯网——每日最新资讯28at.com

ListPsj28资讯网——每日最新资讯28at.com

getRequiredOptions()Psj28资讯网——每日最新资讯28at.com

获得必须的选项集合Psj28资讯网——每日最新资讯28at.com

booleanPsj28资讯网——每日最新资讯28at.com

hasLongOption(String opt)Psj28资讯网——每日最新资讯28at.com

判断是否存在选项Psj28资讯网——每日最新资讯28at.com

booleanPsj28资讯网——每日最新资讯28at.com

hasOption(String opt)Psj28资讯网——每日最新资讯28at.com

判断是否存在选项Psj28资讯网——每日最新资讯28at.com

booleanPsj28资讯网——每日最新资讯28at.com

hasShortOption(String opt)Psj28资讯网——每日最新资讯28at.com

判断是否存在选项Psj28资讯网——每日最新资讯28at.com

解析阶段

主要对输入参数的解析,也就是main方法的参数,默认提供下面3中语法解析的支持:Psj28资讯网——每日最新资讯28at.com

  • DefaultParser:提供了基础的解析功能,能解析简单的命令行参数。(比如:java -Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo)
  • PosixParser:提供了解析POSIX形式参数的功能。(比如:tar -zxvf foo.tar.gz)
  • GnuParser:提供了解析长参数及Java命令中参数的功能。(比如:du --human-readable --max-depth=1)

询问阶段

基于上一步解析后,会将参数解析成CommandLine,结合Option中的配置,需要我们完成各种配置、参数匹配后的业务处理流程,类型下面这样:Psj28资讯网——每日最新资讯28at.com

if( commandLine.hasOption("help") ){          helper.printHelp("calendar [options] /n/nwhere options include:", null, options, null, false);          return;      }      if( commandLine.hasOption("version") ){          printResult("1.0.0");          return;      }

解析的过程有时候会比较些复杂,示例中是针对单一选项的分支,当多个选项混合使用时,比如tar -zxvf xxx.tar.gz这样的,当然前提是我们定义的CLI支持这种风格。Psj28资讯网——每日最新资讯28at.com

示例

下面通过一个简单的示例看下如何构建一个CLI的工具:该示例的作用是按指定格式输出当前日期:Psj28资讯网——每日最新资讯28at.com

clendar -o yyyy-MM-dd
  • 定义配置项
private static Options initOptions() {        Options options = new Options();        options.addOption(Option.builder("H")                .longOpt("help")                .desc("show help information").build());        options.addOption(Option.builder("V")                .longOpt("version")                .desc("show help information").build());        options.addOption(Option.builder("O")                .longOpt("out")                .hasArg(true)                .argName("fmt") // 只是定义                .required(false)                .desc("configure the date output format").build());        return options;    }
  • 解析参数
private static CommandLine parseArguments(Options options, String[] args){        CommandLineParser parser = new DefaultParser();        try {            return parser.parse(options, args);        } catch (ParseException e) {            System.err.println(e.getMessage());        }        return null;    }
  • 询问阶段
private static void handleCommand(Options options, CommandLine commandLine) {        if(ArrayUtils.isEmpty(commandLine.getOptions()) ){            printResult("Please specify options for calendar building or use --help for more info.");            return;        }        if( commandLine.hasOption("help") ){            helper.printHelp("calendar [options] /n/nwhere options include:", null, options, null, false);            return;        }        if( commandLine.hasOption("version") ){            printResult("1.0.0");            return;        }        if( commandLine.hasOption("out") ){            String fmt = commandLine.getOptionValue("out");            if(StringUtils.isEmpty(fmt)){                fmt = "yyyy-MM-dd HH:mm:ss";            }            printResult(DateFormatUtils.format(new Date(), fmt));            return;        }        // calendar: 'x' is not a git command. See 'calendar --help'.        helper.printHelp(String.format("calendar: '%s' is not a calendar command. See 'calendar --help'.", Arrays.toString(commandLine.getArgs())), options, false);    }

定义程序入口:Psj28资讯网——每日最新资讯28at.com

public static void main(String[] args) {        // 定义阶段        Options options = initOptions();        // 解析阶段        CommandLine commandLine = parseArguments(options, args);        // 询问阶段        handleCommand(options, commandLine);    }

打包

这里我们引入maven-assembly-plugin插件,主要帮助在打包时将依赖包一并写入jar文件,同时将入口文件定义到manifest:Psj28资讯网——每日最新资讯28at.com

<plugin>    <groupId>org.apache.maven.plugins</groupId>    <artifactId>maven-assembly-plugin</artifactId>    <version>3.3.0</version>    <executions>        <execution>            <id>package-jar-with-dependencies</id>            <phase>package</phase>            <goals>                <goal>single</goal>            </goals>            <configuration>                <archive>                    <manifest>                        <mainClass>${main-class}</mainClass>                    </manifest>                </archive>                <descriptorRefs>                    <!-- bin,jar-with-dependencies,src,project -->                    <descriptorRef>jar-with-dependencies</descriptorRef>                </descriptorRefs>            </configuration>        </execution>    </executions></plugin>

可以直接通过maven插件或者下的命令,将上面的代码打包成jar文件Psj28资讯网——每日最新资讯28at.com

mvn clean package

测试jar

如果安装上面的配置,最终会在项目target目录输出一个以jar-with-dependencies为后缀的jar文件,通过下面的命令可以测试cli命令Psj28资讯网——每日最新资讯28at.com

java -jar ./target/calendar-jar-with-dependencies.jar -h

这样的CLI可不是我们想要的,一来需要依赖JRE的运行环境,同时调用极其不方便。Psj28资讯网——每日最新资讯28at.com

生成exe

如果你看过之前的文章,关于GraalVM的使用,按照文档下载并配置好运行环境后,可以通过下面的命令对上一步的jar文件进一步处理Psj28资讯网——每日最新资讯28at.com

native-image -jar [jar] -o [name]Psj28资讯网——每日最新资讯28at.com

native-image -jar ./target/calendar-jar-with-dependencies.jar -o calendar

通过上面的命令会生成一个calendar.exe文件,这样将其加入到环境变量后,则可以在windows平台终端上使用了Psj28资讯网——每日最新资讯28at.com

对于不喜欢直接使用命令的,当然这里也可以使用插件exec-maven-plugin,在maven生命周期package阶段,自动执行上面的命令,这样整个过程只需要执行mvn clean package即可Psj28资讯网——每日最新资讯28at.com

<plugin>    <groupId>org.codehaus.mojo</groupId>    <artifactId>exec-maven-plugin</artifactId>    <version>3.1.0</version>    <executions>        <execution>            <id>native-image-app</id>            <phase>package</phase>            <goals>                <goal>exec</goal>            </goals>            <configuration>                <environmentVariables>                </environmentVariables>                <!-- native-image -jar ./target/tool-jar-with-dependencies.jar -o tool -->                <executable>native-image</executable>                <arguments>                    <argument>-jar</argument>                    <argument>${project.basedir}/target/${project.build.finalName}-jar-with-dependencies.jar</argument>                    <argument>-o</argument>                    <argument>${project.build.finalName}</argument>                </arguments>            </configuration>        </execution>    </executions></plugin>

测试exe

在终端执行下面的命令接口看到预期的结果:Psj28资讯网——每日最新资讯28at.com

calendar.exe -O yyyy-MM-dd

总结

总的来说,Apache Commons CLI是一个非常强大的工具,可以帮助你轻松地处理命令行参数。无论你的应用程序需要处理多少个参数,或者这些参数的类型是什么, Commons CLI都可以提供帮助。Psj28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-41684-0.html怎么基于Java编写一个CLI工具?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Go语言 字符串拼接方式与性能比较,分析过没?

下一篇: Spring6提供的四种远程接口调用神器!你知道那种?

标签:
  • 热门焦点
  • 官方承诺:K60至尊版将会首批升级MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版将会搭载天玑9200+处理器和独显芯片X7的同时,Redmi给出了官方承诺,K60至尊重大更新首批升级,会首批推送MIUI 15。也就是说虽然
  • 6月iOS设备好评榜:第一蝉联榜首近一年

    作为安兔兔各种榜单里变化最小的那个,2023年6月的iOS好评榜和上个月相比没有任何排名上的变化,仅仅是部分设备好评率的下降,长年累月的用户评价和逐渐退出市场的老款机器让这
  • 在线图片编辑器,支持PSD解析、AI抠图等

    自从我上次分享一个人开发仿造稿定设计的图片编辑器到现在,不知不觉已过去一年时间了,期间我经历了裁员失业、面试找工作碰壁,寒冬下一直没有很好地履行计划.....这些就放在日
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 2023年,我眼中的字节跳动

    此时此刻(2023年7月),字节跳动从未上市,也从未公布过任何官方的上市计划;但是这并不妨碍它成为中国最受关注的互联网公司之一。从2016-17年的抖音强势崛起,到2018年的&ldquo;头腾
  • AMD的AI芯片转单给三星可能性不大 与台积电已合作至2nm制程

    据 DIGITIMES 消息,英伟达 AI GPU 出货逐季飙升,接下来 AMD MI 300 系列将在第 4 季底量产。而半导体业内人士表示,近日传出 AMD 的 AI 芯片将转单给
  • Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
  • DRAM存储器10月价格下跌,NAND闪存本月价格与上月持平

    10月30日,据韩国媒体消息,自今年年初以来一直在上涨的 DRAM 存储器的交易价格仅在本月就下跌了近 10%,此次是全年首次降价,而NAND 闪存本月价格与上月持平。市
  • onebot M24巧系列一体机采用轻薄机身设计,现已在各平台开售

    onebot M24 巧系列一体机目前已在线上线下各平台同步开售。onebot M24 巧系列采用一体化轻薄机身设计,最薄处为 10.15mm,拥有宝石红、午夜蓝、石墨绿、雅致
Top