<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 262,  comments - 221,  trackbacks - 0
    【一】需求

    前面我們使用了commons io包中的DirectoryWalker和IOFileFilter來進行復雜條件的搜索,但是這個程序有幾個問題:
     ①選項都是hard code在代碼里面,難以修改
     ②有些選項是必需的,有些選項是可選的
     ③有些選項是不帶參數的,有些選項是要帶參數的

    如果我們希望這個程序能夠更加靈活,根據人性化,那么我們需要提供一個界面,無論是普通的命令行、控制臺交互、GUI界面。而且還必須讓用戶自行決定是否要使用該選項。程序必須自動根據已有的條件動態組合

    【二】簡單而功能強大的commons CLI

    Apache commons CLI是一個開源的,用于處理命令行的工具包。這個包目前的穩定版本是1.2,他非常簡單只有20個左右的class,但提供了幾乎所以可以用到的命令行功能。它的主頁在這里:Apache commons CLI

    根據CLI的邏輯,每一個命令行的處理都可以分為3個步驟:定義、解析、交互
     ①定義:定義命令行的各種選項屬性(包括縮寫、全寫、是否必須、是否帶參數、參數個數限制)
     ②解析:使用解析器對命令行選項列表進行解析
     ③交互:從解析好的命令行查詢用戶輸入的參數值并進行處理


    這里需要區分兩個名詞:選項(option)和參數(arguments)。選項是用來表明功能或者參數的意思的,例如“-d”這個字符串就是一個選項,它可以表示一個日期。那么如果我們需要指定一個日期用于處理,就需要在“-d”后面再加上一個具體值,這個具體值就是參數(argument)。

    對應于這3個過程,我們來認識幾個重要的類:

    ①定義階段
     A.Option:這個類用于定義命令行的選項,你可以通過構造方法來定義一個選項
     B.Options:Option的容器,用于存儲多個Option
     C.OptionBuilder:使用描述性API來構建Option,而非直接使用Option的構造方法

    ②解析階段
     A.CommandLineParser:接口,定義了parse方法由實現類實現
     B.PosixParser:Posix風格的命令行解析器
     C.GnuParser:GNU風格的命令行解析器

    ③交互階段
     A.CommandLine:解析后的命令行對象,可以用于查詢選項的值

    【三】CLI快速入門

    通常情況下如果命令的選項比較簡單我們使用構造方法就夠了,但是當選項的屬性比較復雜或者描述性文本比較長時,使用構建器會令到程序的可讀性更進一步。下面我們來看看這個需求:

    有這樣一個命令行,它具備如下的選項和參數組合:
     ①一個目錄選項:-d,帶參數值,必須選項
     ②一個日期選項:-D,帶參數值,全寫--date,可選項
     ③一個日期范圍選項:-r,帶參數值,當-D出現時為必選項,否則該選項無效
     ④一個文件名前綴選項:-p,帶參數值,可以有多個前綴名,以逗號分隔,可選項
     ⑤一個文件擴展名選項:-s,帶參數值,可以有多個擴展名,以逗號分隔,可選項
     ⑥一個文件大小選項:-S,帶參數值,全寫--file-size,可選項
     ⑦一個文件大小閥值選項:-l,帶參數值,當-S出現時為必選項,否則該選項無效
     ⑧一個幫助信息選項:-h,無參數值

    【四】代碼示例

    package example.io;

    import org.apache.commons.cli.CommandLine;
    import org.apache.commons.cli.CommandLineParser;
    import org.apache.commons.cli.HelpFormatter;
    import org.apache.commons.cli.Option;
    import org.apache.commons.cli.OptionBuilder;
    import org.apache.commons.cli.Options;
    import org.apache.commons.cli.ParseException;
    import org.apache.commons.cli.PosixParser;

    /**
     * <pre>
     * 用于指定各種搜索條件
     * </pre>
     
    */

    public class SearchCommandLineProcesser implements CommandLineProcesser {

        
    /**
         * <pre>
         * ①一個目錄選項:-d,帶參數值,必須選項 
         * ②一個日期選項:-D,帶參數值,全寫--date,可選項
         * ③一個日期范圍選項:-r,帶參數值,當-D出現時為必選項,否則該選項無效
         * ④一個文件名前綴選項:-p,帶參數值,可以有多個前綴名,以逗號分隔,可選項 
         * ⑤一個文件擴展名選項:-s,帶參數值,可以有多個擴展名,以逗號分隔,可選項 
         * ⑥一個文件大小選項:-S,帶參數值,全寫--file-size,可選項 
         * ⑦一個文件大小閥值選項:-l,帶參數值,當-S出現時為必選項,否則該選項無效 
         * ⑧一個幫助信息選項:-h,無參數值
         * </pre>.
         
    */


        
    private Options searchOpts = new Options();

        
    private CommandLine cl = null;

        
    /**
         * The main method.
         * 
         * 
    @param args the arguments
         
    */

        
    public static void main(String[] args) {
            SearchCommandLineProcesser processer 
    = new SearchCommandLineProcesser();
            processer.run(args);
            processer.validte();
        }


        
    /**
         * Instantiates a new search command line processer.
         
    */

        
    public SearchCommandLineProcesser() {
            String desc 
    = "Specify the directory where search start";
            Option optStartDir 
    = OptionBuilder.withDescription(desc).isRequired(false)
                    .hasArgs().withArgName(
    "START_DIRECTORY").create('d');
            searchOpts.addOption(optStartDir);
        }


        
    /**
         * Set rule for command line parser, run parsing process
         * 
         * 
    @param args the args
         
    */

        
    private void run(String[] args) {
            setDate();
            setDateRange();
            setPrefix();
            setSuffix();
            setSize();
            setSizeRange();
            setHelp();
            runProcess(searchOpts, args, 
    new PosixParser());
        }


        
    /**
         * Sets the date.
         
    */

        
    public void setDate() {
            String desc 
    = "Specify the file create date time";
            Option optDate 
    = OptionBuilder.withDescription(desc).isRequired(false)
                    .hasArgs().withArgName(
    "FILE_CREATE_DATE").withLongOpt("date")
                    .create(
    'D');
            searchOpts.addOption(optDate);
        }


        
    /**
         * Sets the date range.
         
    */

        
    public void setDateRange() {
            StringBuffer desc 
    = new StringBuffer(
                    
    "Specify acceptance date range for cutoff date specify by option -d");
            desc.append(
    "if true, older files (at or before the cutoff)");
            desc.append(
    "are accepted, else newer ones (after the cutoff)");
            Option optDateRange 
    = null;

            optDateRange 
    = OptionBuilder.withDescription(desc.toString())
                    .isRequired(
    false).hasArg().withArgName("DATE_RANGE")
                    .create(
    'r');
            searchOpts.addOption(optDateRange);
        }


        
    /**
         * Sets the prefix.
         
    */

        
    public void setPrefix() {
            String desc 
    = "Specify the prefix of file, multiple prefixes can be split by comma";
            Option optPrefix 
    = OptionBuilder.withDescription(desc)
                    .isRequired(
    false).hasArgs().withArgName("FILE_PREFIXES")
                    .create(
    'p');
            searchOpts.addOption(optPrefix);
        }


        
    /**
         * Sets the suffix.
         
    */

        
    public void setSuffix() {
            String desc 
    = "Specify the suffix of file, multiple suffixes can be split by comma";
            Option optSuffix 
    = OptionBuilder.withDescription(desc)
                    .isRequired(
    false).hasArgs().withArgName("FILE_SUFFIXES")
                    .create(
    's');
            searchOpts.addOption(optSuffix);
        }


        
    /**
         * Sets the size.
         
    */

        
    public void setSize() {
            String desc 
    = "Spcify the file size";
            Option optSize 
    = OptionBuilder.withDescription(desc).isRequired(false)
                    .hasArg().withArgName(
    "FILE_SIZE_WITH_LONG_VALUE").withLongOpt(
                            
    "file-size").create('S');
            searchOpts.addOption(optSize);
        }


        
    /**
         * Sets the size range.
         
    */

        
    public void setSizeRange() {
            StringBuffer desc 
    = new StringBuffer(
                    
    "Specify acceptance size threshold for file specify by option -S");
            desc.append(
    "if true, files equal to or larger are accepted,");
            desc.append(
    "otherwise smaller ones (but not equal to)");
            Option optDateRange 
    = null;

            optDateRange 
    = OptionBuilder.withDescription(desc.toString())
                    .isRequired(
    false).hasArg().withArgName("SIZE_THRESHOLD")
                    .create(
    'l');
            searchOpts.addOption(optDateRange);
        }


        
    /**
         * Sets the help.
         
    */

        
    public void setHelp() {
            String desc 
    = "Print help message and all options information";
            Option optHelp 
    = OptionBuilder.withDescription(desc).isRequired(false)
                    .create(
    'h');
            searchOpts.addOption(optHelp);
        }


        
    /**
         * Run process.
         * 
         * 
    @param opts the opts
         * 
    @param args the args
         * 
    @param parser the parser
         
    */

        
    public void runProcess(Options opts, String[] args, CommandLineParser parser) {
            
    try {
                cl 
    = process(searchOpts, args, parser);
            }
     catch (ParseException e) {            
                System.out.println(
    "Error on compile/parse command: "
                        
    + e.getMessage());
                printHelp(opts);
                System.exit(
    -1);
            }

            Option[] allOpts 
    = cl.getOptions();
            Option opt 
    = null;
            
    for (int i = 0; i < allOpts.length; i++{
                opt 
    = allOpts[i];
                
    if("h".equals(opt.getOpt())) {
                    printHelp(opts);
                    System.exit(
    0);
                }

                System.out.println(
    "Option name: -" + opt.getOpt()
                        
    + ", and value = " + getOptValues(opt.getOpt(), ","));
            }

        }


        
    /*
         * (non-Javadoc)
         * 
         * @see example.io.CommandLineProcesser#process(org.apache.commons.cli.Options,
         *      java.lang.String[], org.apache.commons.cli.CommandLineParser)
         
    */

        
    public CommandLine process(Options options, String[] args,
                CommandLineParser parser) 
    throws ParseException {                
            
    return parser.parse(options, args);
        }


        
    /**
         * Validte required option and optional options
         
    */

        
    private void validte() {
            
            
    // Validate directory option
            String directory = getOptValue("d");
            
    if (directory == null{
                System.out.println(
    "Missing start directory, ignore and exit");
                System.exit(
    -1);
            }

            
    // Validate date option
            String date = (getOptValue("D"== null? getOptValue("date")
                    : getOptValue(
    "D");
            String dateRange 
    = getOptValue("r");
            
    if(date != null && (dateRange == null)) {
                System.out.println(
    "Missing option -D/--date, exit immediately");
                System.exit(
    -1);
            }
    else if (date == null && (dateRange != null)) {
                System.out.println(
    "Date not specified, ignore option -r");
            }

            
    // Validate size option
            String size = (getOptValue("S"== null? getOptValue("file-size")
                    : getOptValue(
    "S");
            String sizeRange 
    = getOptValue("l");
            
    if(size != null && (sizeRange == null)) {
                System.out.println(
    "Missing option -S/--file-size, exit immediately");
                System.exit(
    -1);
            }
    else if (size == null && (sizeRange != null)) {
                System.out.println(
    "File size not specified, ignore option -l");
            }

        }


        
    /**
         * Prints the help.
         * 
         * 
    @param options the options
         
    */

        
    public void printHelp(Options options) {
            String formatstr 
    = "java example.io.SearchCommandLineProcesser [-h][-d][-D/--date<-r>][-p][-s][-S/--size<-l>]";
            HelpFormatter formatter 
    = new HelpFormatter();
            formatter.printHelp(formatstr, options);
        }


        
    /*
         * (non-Javadoc)
         * 
         * @see example.io.CommandLineProcesser#getOptValue(java.lang.String)
         
    */

        
    public String getOptValue(String opt) {
            
    return (cl != null? cl.getOptionValue(opt) : "";
        }


        
    /*
         * (non-Javadoc)
         * 
         * @see example.io.CommandLineProcesser#getOptValues(java.lang.String)
         
    */

        
    public String[] getOptValues(String opt) {
            
    return (cl != null? cl.getOptionValues(opt) : new String[] "" };
        }


        
    /*
         * (non-Javadoc)
         * 
         * @see example.io.CommandLineProcesser#getOptValues(java.lang.String,
         *      java.lang.String)
         
    */

        
    public String getOptValues(String opt, String valueSeparater) {
            String[] values 
    = getOptValues(opt);
            StringBuffer sb 
    = new StringBuffer();
            
    for (int i = 0; i < values.length; i++{
                sb.append(values[i]).append(valueSeparater);
            }

            
    return sb.subSequence(0, sb.length() - 1).toString();
        }


    }

    【五】結果演示

    ①演示使用方法:

    控制臺參數為:-h




    ②正確命令格式

    控制臺命令格式為:-d E:/Other/Picture/私人/ -D "2010-01-01-01 00:00:00" -r true -p IMG_,DSMG, -s .jpg,.gif --file-size 1024*1024*2 -l true



    ③錯誤命令格式

    控制臺命令格式為:-d E:/Other/Picture/私人/ -D "2010-01-01-01 00:00:00" -r true -p IMG_,DSMG, -s .jpg,.gif --file-size 1024*1024*2 -l true -Q




    -------------------------------------------------------------
    生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
    posted on 2010-04-02 14:20 Paul Lin 閱讀(1073) 評論(0)  編輯  收藏 所屬分類: J2SE
    <2010年4月>
    28293031123
    45678910
    11121314151617
    18192021222324
    2526272829301
    2345678

    常用鏈接

    留言簿(21)

    隨筆分類

    隨筆檔案

    BlogJava熱點博客

    好友博客

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 99爱免费观看视频在线| 久久精品国产精品亚洲艾| 国产成人精品免费视频网页大全 | 精品免费视在线观看| 亚洲国产美女精品久久久| 亚洲第一网站免费视频| 亚洲精品无码久久千人斩| www.91亚洲| 亚洲bt加勒比一区二区| 亚洲成AⅤ人影院在线观看| 毛片免费在线观看网站| 57pao一国产成永久免费| 免费无码又爽又刺激高潮软件| 免费播放国产性色生活片| 亚洲中文字幕精品久久| 亚洲人6666成人观看| 久久精品国产亚洲AV香蕉| 亚洲午夜福利在线观看| 国产精品亚洲美女久久久| 国产日产成人免费视频在线观看| 青春禁区视频在线观看直播免费| 亚洲人成免费网站| **俄罗斯毛片免费| 亚洲一区免费在线观看| 亚洲第一网站免费视频| 最近中文字幕完整免费视频ww| 无码人妻精品中文字幕免费| 两个人看的www免费视频| 两性色午夜视频免费播放| 国产中文字幕在线免费观看| 两性色午夜视频免费网| 黄网站免费在线观看| 日韩视频免费在线观看| 无码人妻一区二区三区免费n鬼沢 无码人妻一区二区三区免费看 | 亚洲乱码一区av春药高潮| 亚洲性猛交xx乱| 亚洲中文字幕在线无码一区二区| 亚洲va在线va天堂va手机| 亚洲男人的天堂久久精品| 国产亚洲精品国产| 亚洲成A人片在线观看WWW|