Args4J 使用指南
Args4J 是一個用來出來命令行的工具.
在實際的項目中用到命令行的并不是很常見,但當真正使用到時,特別是在程序啟動時配置一下參數的時候就很有用了,如果參數很多的話,一個一個解析命令行還是比較麻煩的.這時使用Args4J就相當好辦了. 在本文中我們來看看Args4J的使用,當需要時能提供一個解決方案.
Args4J使用一個被稱為Option類的類來保存輸入的參數,讓后根據該類來應用參數,每個參數可以對應一個類中的屬性,該屬性用Annotation注釋,在Annotation中給出該參數 的選項, 還可以配置其他有用的信息.該Annotation就是 Option 注解: 該注解的doc如下:
Marks a field/setter that receives a command line switch value.
This annotation can be placed on a field of type T or the method of the form void methodName(T value). Its access modified can be anything, but if it's not public, your application needs to run in a security context that allows args4j to access the field/method (see AccessibleObject.setAccessible(boolean)
.
The behavior of the annotation differs depending on T --- the type of the field or the parameter of the method.
Boolean Switch
When T is boolean , it represents a boolean option that takes the form of "-OPT". When this option is set, the property will be set to true.
String Switch
When T is String
, it represents an option that takes one operand. The value of the operand is set to the property.
Enum Switch
When T is derived from Enum
, it represents an option that takes an operand, which must be one of the enum constant. The comparion between the operand and the enum constant name is done in a case insensitive fashion.
For example, the following definition will represent command line options like "-coin penny" or "-coin DIME" but things like "-coin" or "-coin abc" are errors.
enum Coin { PENNY,NICKEL,DIME,QUARTER }
class Option {
@Option(name="-coin")
public Coin coin;
}
File Switch
When T is a File
, it represents an option that takes a file/directory name as an operand.
該注解有5各域 其中name是必須的,其他四個是可選的.如下所示,關于該注解的詳細Doc請查看 其docs.
Required Element Summary
|
?String
|
name
??????????Name of the option, such as "-foo" or "-bar". |
?
Optional Element Summary |
---|
?Class<? extends OptionHandler> | handler ??????????Specify the OptionHandler that processes the command line arguments. |
?String | metaVar ??????????When the option takes an operand, the usage screen will show something like this: |
?boolean | required ??????????Specify that the option is mandatory. |
?String | usage ??????????Help string used to display the usage screen. |
當命令行設定后 其使用方式和java 命令里面的參數使用方式一樣 如:java -cp ./calssPath/.......
下面通過一個例子來解釋:
001?/*
002??*?Created?on?2006-2-21
003??*?@author?icerain
004??*/
005?package?test.args4j;
006?
007?import?org.kohsuke.args4j.Argument;
008?import?org.kohsuke.args4j.CmdLineException;
009?import?org.kohsuke.args4j.CmdLineParser;
010?import?org.kohsuke.args4j.ExampleMode;
011?import?org.kohsuke.args4j.Option;
012?import?org.kohsuke.args4j.spi.BooleanOptionHandler;
013?
014?import?java.io.File;
015?import?java.io.IOException;
016?import?java.util.ArrayList;
017?import?java.util.List;
018?
019?public?class?TestArgs4J?{
020???//?利用Option注解來定義一個boolean?命令行參數?其參數name為?-re?,required指定該參數是必須的
021???@Option(name?=?"-re",?usage?=?"recursively?run?something",?required?=?true)
022???private?boolean?recursive;
023?
024???//利用Option注解定義一個File?命令行參數,?name為-o,?輸入時候知道該file的路徑就可以了
025???//metaVar?用來設定顯示?使用方式時候的輸出,這個輸出為-o?OUTPUT?:?output?to?this?file
026???//如果不指定該屬性?則使用默認的代替?為-o?FILE?:?output?to?this?file
027???@Option(name?=?"-o",?usage?=?"output?to?this?file",?metaVar?=?"OUTPUT")
028???private?File?out?=?new?File(".");
029?
030???//If?'usage'?value?is?empty,?the?option?will?not?be?displayed
031?????//?in?the?usage?screen.
032???//注意該處沒有指定?usage?屬性?或者指定usage?但是其值為空的?如usage?=?"",這樣當使用
033???//parser.printExample(ExampleMode.ALL)?請注意下面第92行的輸出
034???@Option(name?=?"-str",?required?=?true)
035???//@Option(name?=?"-str",?usage?=?"測試",?required?=?true)??//?該行?-str參數有用
036???//?no?usage
037???
038???private?String?str?=?"(default?value)";
039?
040???//?整數參數
041???@Option(name?=?"-n",?usage?=?"repeat?<n>?times\nusage?can?have?new?lines?in?it?and?also?it?can?be?verrry?long")
042???private?int?num?=?-1;
043?
044???//?using?'handler=...'?allows?you?to?specify?a?custom?OptionHandler
045???//?implementation?class.?This?allows?you?to?bind?a?standard?Java?type
046???//?with?a?non-standard?option?syntax
047???//指定一個特定的handler?
048???@Option(name?=?"-custom",?handler=BooleanOptionHandler.class,usage="boolean?value?for?checking?the?custom?handler")
049???private?boolean?data;
050?
051???//?receives?other?command?line?parameters?than?options
052???@Argument
053???private?List<String>?arguments?=?new?ArrayList<String>();
054?
055???public?static?void?main(String[]?args)?throws?IOException?{
056?????new?TestArgs4J().doMain(args);
057???}
058?
059???public?void?doMain(String[]?args)?throws?IOException?{
060?????//Creates?a?new?command?line?owner?that?parses?arguments/options
?????????????and?set?them?into?the?given?object.
061?????CmdLineParser?parser?=?new?CmdLineParser(this);
062?
063?????try?{
064???????//?parse?the?arguments.
065???????parser.parseArgument(args);
066?
067???????//?you?can?parse?additional?arguments?if?you?want.
068???????//?parser.parseArgument("more","args");
069?
070???????//?after?parsing?arguments,?you?should?check
071???????//?if?enough?arguments?are?given.
072???????if?(arguments.isEmpty())
073?????????throw?new?CmdLineException("No?argument?is?given");
074?
075?????}?catch?(CmdLineException?e)?{
076???????//?if?there's?a?problem?in?the?command?line,
077???????//?you'll?get?this?exception.?this?will?report
078???????//?an?error?message.
079???????System.err.println(e.getMessage());??//打印出錯消息
080???????System.err.println("java?SampleMain?[options...]?arguments...");
081???????//?print?the?list?of?available?options
082???????parser.printUsage(System.err);??//?打印參數的用法
083???????System.err.println();
084?
085???????System.err.println("測試!!!!!");
086???????//?print?option?sample.?This?is?useful?some?time
087???????System.err.println("??Example:?java?SampleMain"
088???????????+?parser.printExample(ExampleMode.ALL));???????
// 注意 在Option中如果沒有指定 usage 屬性,
089???????System.err.println("/n?2.........");???????????????
//
則這兩行程序不會輸出該參數的使用的
090?
091???????System.err.println("?2?Example2:?java?SampleMain"?
//
注意 在Option中如果沒有指定 usage 屬性,
092???????????+?parser.printExample(ExampleMode.REQUIRED));??
//
則這兩行程序不會輸出該參數的使用的
093???????return;
094?????}
095?
096?????//?this?will?redirect?the?output?to?the?specified?output
097?????System.out.println(out);
098?
099?????if?(recursive)
100???????System.out.println("-r?flag?is?set");
101?
102?????if?(data)
103???????System.out.println("-custom?flag?is?set");
104?
105?????System.out.println("-str?was?"?+?str);
106?
107?????if?(num?>=?0)
108???????System.out.println("-n?was?"?+?num);
109?
110?????//?access?non-option?arguments
111?????System.out.println("other?arguments?are:");
112?????for?(String?s?:?arguments)
113???????System.out.println(s);
114???}
115?
116?}
當不使用命令行時候 輸入信息如下:
Option "-re" is required
java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
usage can have new lines in it and also it can be verrrrrrr
rrrrrrrrrrry long
-o OUTPUT : output to this file
-re : recursively run something
測試!!!!!
Example: java SampleMain -custom -n N -o OUTPUT -re??
// 注意該處沒有 -str的出現/n 2.........
2 Example2: java SampleMain -re
?// 注意該處沒有 -str的出現當使用 -re 為命令行輸入時,輸出如下:// 后為作者加的注釋 不是輸出
Option "-str" is required?
?//也要指定-str該參數 java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
usage can have new lines in it and also it can be verrrrrrr
rrrrrrrrrrry long
-o OUTPUT : output to this file
-re : recursively run something
測試!!!!!
Example: java SampleMain -custom -n N -o OUTPUT -re
/n 2.........
2 Example2: java SampleMain -re
當使用-re -str some 為命令行輸入時,結果如下:這是由于的73 行的判斷引起的
No argument is given
java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
usage can have new lines in it and also it can be verrrrrrr
rrrrrrrrrrry long
-o OUTPUT : output to this file
-re : recursively run something
測試!!!!!
Example: java SampleMain -custom -n N -o OUTPUT -re
/n 2.........
2 Example2: java SampleMain -re
使用-custom -n 2 -re -str some otherstring 為命令行輸入時的 結果如下:
.??? // file
-r flag is set
-custom flag is set
-str was some
-n was 2
other arguments are:
otherstring
當使用-custom -n 2 -re -str some -o log.txt otherstring 時候的輸出如下:
log.txt
-r flag is set
-custom flag is set
-str was some
-n was 2
other arguments are:
otherstring
當使用一個不存在的參數時候 會有Exception的 例如:-custom -ee 2 -re -str some -o log.txt otherstring
其中-ee參數不存在 結果如下:
"-ee" is not a valid option
java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
......
由以上的實例可以看出 args4J 取得命令行的輸入參數,然后根據保存參數的類中的屬性類型比較
?
并轉換為適當的值, 然后我們可以使用這些屬性了,這樣就免去了自己判斷args 的麻煩了,
當默認的Handler不滿足你的要求時 可以自己擴展Handler實現,關于這點請參考Args4J的測試用例,
From : java 愛好者? by : icess