Footsteps on my way !
perl/linux/测序分析

java使用GetOpt设置读取命令行参数

在shell工具中,有专门的getopt函数,使用方法如下所示:

while getopts "d:t:vh" opt; do  
    case "${opt}" in  
    "d")  
        DATE="${OPTARG}"  
        ;;  
    "t")  
        ID="${OPTARG}"  
        ID2=`echo $ID | awk -F "_" '{print $2}'`  
        ;;  
    "v")  
        printVersionInfo  
        exit 0  
        ;;   
    "h")  
        printHelpInfo
        exit 0
        ;;
    esac
done

其中的”d:t:vh”就是可以接收的选项类型,其中-d和-t意味着可以其后面可以接收参数,而-v和-h后面因为没有:,表示不可以接收参数,只用于单独使用。于是使用这个shell脚本的方式就大概如下:

./example.sh –d “d的参数” –t “t的参数”  
./example.sh –h  
./example.sh –v

GetOpt在Java1.8的全称为:

com.sun.org.apache.xalan.internal.xsltc.cmdline.getopt.GetOpt

Java程序员不能调用sun.*的相关包,以下是oracle给出的原因:

http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html

既然不能够直接调用,就拷贝过来,反正依赖也不多。

只需要少许改动,解除与ErrorMsg类的依赖,删除一个MissingOptException(同样改成IllegalArgumentException),就可以直接使用了,以下就是修改后的代码:

/* 
 * Copyright (c) 2007-2012, Oracle and/or its affiliates. All rights reserved. 
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 
 */  
/* 
 * Copyright 2001-2004 The Apache Software Foundation. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */  
/* 
 * $Id: GetOpt.java,v 1.2.4.1 2005/08/31 11:46:04 pvedula Exp $ 
 */  
  
import java.util.ArrayList;  
import java.util.List;  
import java.util.ListIterator;  
  
  
/** 
 * GetOpt is a Java equivalent to the C getopt() library function 
 * discussed in man page getopt(3C). It provides command line 
 * parsing for Java applications. It supports the most rules of the 
 * command line standard (see man page intro(1)) including stacked 
 * options such as '-sxm' (which is equivalent to -s -x -m); it 
 * handles special '--' option that signifies the end of options. 
 * Additionally this implementation of getopt will check for 
 * mandatory arguments to options such as in the case of 
 * '-d ' it will throw a MissingOptArgException if the 
 * option argument '' is not included on the commandline. 
 * getopt(3C) does not check for this. 
 * 
 * @author G Todd Miller 
 */  
public class GetOpt {  
  
    public static final String ILLEGAL_CMDLINE_OPTION_ERR = "ILLEGAL_CMDLINE_OPTION_ERR";  
  
    public GetOpt(String[] args, String optString) {  
        theOptions = new ArrayList();  
        int currOptIndex = 0;  
        theCmdArgs = new ArrayList();  
        theOptionMatcher = new OptionMatcher(optString);  
        // fill in the options list  
        for (int i = 0; i < args.length; i++) { String token = args[i]; int tokenLength = token.length(); if (token.equals("--")) { // end of opts currOptIndex = i + 1; // set index of first operand break; // end of options } else if (token.startsWith("-") && tokenLength == 2) { // simple option token such as '-s' found theOptions.add(new Option(token.charAt(1))); } else if (token.startsWith("-") && tokenLength > 2) {  
                // stacked options found, such as '-shm'  
                // iterate thru the tokens after the dash and  
                // add them to theOptions list  
                for (int j = 1; j < tokenLength; j++) {  
                    theOptions.add(new Option(token.charAt(j)));  
                }  
            } else if (!token.startsWith("-")) {  
                // case 1- there are not options stored yet therefore  
                // this must be an command argument, not an option argument  
                if (theOptions.size() == 0) {  
                    currOptIndex = i;  
                    break;              // stop processing options  
                } else {  
                    // case 2-  
                    // there are options stored, check to see if  
                    // this arg belong to the last arg stored  
                    int indexoflast = 0;  
                    indexoflast = theOptions.size() - 1;  
                    Option op = (Option) theOptions.get(indexoflast);  
                    char opLetter = op.getArgLetter();  
                    if (!op.hasArg() && theOptionMatcher.hasArg(opLetter)) {  
                        op.setArg(token);  
                    } else {  
                        // case 3 -  
                        // the last option stored does not take  
                        // an argument, so again, this argument  
                        // must be a command argument, not  
                        // an option argument  
                        currOptIndex = i;  
                        break;                  // end of options  
                    }  
                }  
            }// end option does not start with "-"  
        } // end for args loop  
  
        //  attach an iterator to list of options  
        theOptionsIterator = theOptions.listIterator();  
  
        // options are done, now fill out cmd arg list with remaining args  
        for (int i = currOptIndex; i < args.length; i++) {  
            String token = args[i];  
            theCmdArgs.add(token);  
        }  
    }  
  
  
    /** 
     * debugging routine to print out all options collected 
     */  
    public void printOptions() {  
        for (ListIterator it = theOptions.listIterator(); it.hasNext(); ) {  
            Option opt = (Option) it.next();  
            System.out.print("OPT =" + opt.getArgLetter());  
            String arg = opt.getArgument();  
            if (arg != null) {  
                System.out.print(" " + arg);  
            }  
            System.out.println();  
        }  
    }  
  
    /** 
     * gets the next option found in the commandline. Distinguishes 
     * between two bad cases, one case is when an illegal option 
     * is found, and then other case is when an option takes an 
     * argument but no argument was found for that option. 
     * If the option found was not declared in the optString, then 
     * an IllegalArgumentException will be thrown (case 1). 
     * If the next option found has been declared to take an argument, 
     * and no such argument exists, then a MissingOptArgException 
     * is thrown (case 2). 
     * 
     * @return int - the next option found. 
     * @throws IllegalArgumentException, MissingOptArgException. 
     */  
    public int getNextOption() throws IllegalArgumentException {  
        int retval = -1;  
        if (theOptionsIterator.hasNext()) {  
            theCurrentOption = (Option) theOptionsIterator.next();  
            char c = theCurrentOption.getArgLetter();  
            boolean shouldHaveArg = theOptionMatcher.hasArg(c);  
            String arg = theCurrentOption.getArgument();  
            if (!theOptionMatcher.match(c)) {  
//                ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_CMDLINE_OPTION_ERR,  
//                                            new Character(c));  
                throw (new IllegalArgumentException(String.format("%s : %s", ILLEGAL_CMDLINE_OPTION_ERR, new Character(c))));  
            } else if (shouldHaveArg && (arg == null)) {  
                throw (new IllegalArgumentException(String.format("%s : %s", ILLEGAL_CMDLINE_OPTION_ERR, new Character(c))));  
            }  
            retval = c;  
        }  
        return retval;  
    }  
  
    /** 
     * gets the argument for the current parsed option. For example, 
     * in case of '-d ', if current option parsed is 'd' then 
     * getOptionArg() would return ''. 
     * 
     * @return String - argument for current parsed option. 
     */  
    public String getOptionArg() {  
        String retval = null;  
        String tmp = theCurrentOption.getArgument();  
        char c = theCurrentOption.getArgLetter();  
        if (theOptionMatcher.hasArg(c)) {  
            retval = tmp;  
        }  
        return retval;  
    }  
  
    /** 
     * gets list of the commandline arguments. For example, in command 
     * such as 'cmd -s -d file file2 file3 file4'  with the usage 
     * 'cmd [-s] [-d ] ...', getCmdArgs() would return 
     * the list {file2, file3, file4}. 
     * 
     * @return String[] - list of command arguments that may appear 
     * after options and option arguments. 
     * @params none 
     */  
    public String[] getCmdArgs() {  
        String[] retval = new String[theCmdArgs.size()];  
        int i = 0;  
        for (ListIterator it = theCmdArgs.listIterator(); it.hasNext(); ) {  
            retval[i++] = (String) it.next();  
        }  
        return retval;  
    }  
  
  
    private Option theCurrentOption = null;  
    private ListIterator theOptionsIterator;  
    private List theOptions = null;  
    private List theCmdArgs = null;  
    private OptionMatcher theOptionMatcher = null;  
  
    ///////////////////////////////////////////////////////////  
    //  
    //   Inner Classes  
    //  
    ///////////////////////////////////////////////////////////  
  
    // inner class to model an option  
    class Option {  
        private char theArgLetter;  
        private String theArgument = null;  
  
        public Option(char argLetter) {  
            theArgLetter = argLetter;  
        }  
  
        public void setArg(String arg) {  
            theArgument = arg;  
        }  
  
        public boolean hasArg() {  
            return (theArgument != null);  
        }  
  
        public char getArgLetter() {  
            return theArgLetter;  
        }  
  
        public String getArgument() {  
            return theArgument;  
        }  
    } // end class Option  
  
  
    // inner class to query optString for a possible option match,  
    // and whether or not a given legal option takes an argument.  
    //  
    class OptionMatcher {  
        public OptionMatcher(String optString) {  
            theOptString = optString;  
        }  
  
        public boolean match(char c) {  
            boolean retval = false;  
            if (theOptString.indexOf(c) != -1) {  
                retval = true;  
            }  
            return retval;  
        }  
  
        public boolean hasArg(char c) {  
            boolean retval = false;  
            int index = theOptString.indexOf(c) + 1;  
            if (index == theOptString.length()) {  
                // reached end of theOptString  
                retval = false;  
            } else if (theOptString.charAt(index) == ':') {  
                retval = true;  
            }  
            return retval;  
        }  
  
        private String theOptString = null;  
    } // end class OptionMatcher  
}// end class GetOpt

我们先看GetOpt的构造函数,接收两个参数,第一个就是通过public static void main(String[] args)来指定的,也就是传过来的参数;第二个参数就更加重要了,这个是用来设置可接受选项类型的,这也是与shell中的getopt函数有着相同的含义。

下面就是一段关于getOpt函数的简单使用说明,对于每个选项,不用考虑其出现的顺序,这里也同样接收四种类型选项,其中d,t带具体的附加参数,而v,h没有附加参数,只作为帮助以及版本信息显示使用。

GetOpt getOpt = new GetOpt(args, "d:t:vh");  
package net.yangl.getopt;

public class TestGetOpt {
	 
	//java -jar Test.jar  -d "2016-12-2 14:38:37" -t tt -v
	// -h -v  -t 呵呵
	public static void main(String[] args) {
 
		int c;
		GetOpt getOpt = new GetOpt(args, "d:t:vh");
		String dateString;
		String campaignId;
		if ((c = getOpt.getNextOption()) == -1) {
			printHelpInfo();
		}else{
			System.out.println((char) c);
			switch (c) {
			case 'd':
				dateString = getOpt.getOptionArg();
				System.out.println(dateString);
//				break;
			case 't':
				campaignId = getOpt.getOptionArg();
				System.out.println(campaignId);
//				break;
			case 'h':
				printHelpInfo();
				break;
			case 'v':
				printVersionInfo();
				break;
			}
		}
	}
 
	private static void printVersionInfo() {
		System.out.println("WillRun v1.00.20180721");
		
	}
 
	private static void printHelpInfo() {
		System.out.println("  Usage : WillRun [options] -s software");
		System.out.println("  Active software before you run.");
		System.out.println();
		System.out.println("  Options:");
		System.out.println("  -h       Display this help message");
		System.out.println("  -v       Display version");
		System.out.println("  -s       software name you will run");
	}
 
}

使用getNextOption()函数来逐个获取下一个选项,直到返回-1表示没有下一个参数可以处理。通过switch/case语句对每个选项的附加参数进行区分,并结合getOptionArg()返回该选项中的附件参数,并进行处理。

如果输入了不合法的参数字符,就会抛出以下的错误信息(表明a是未定义的参数字符):

java.lang.IllegalArgumentException: ILLEGAL_CMDLINE_OPTION_ERR : a  
       at.utils.GetOpt.getNextOption(GetOpt.java:151)

以上就是java中使用getOpt函数的总体介绍,这对于处理linux形式的参数有着非常好的支持,并且符合程序员的习惯。

尊重他人劳动成果,转载请注明出处:Bluesky's blog » java使用GetOpt设置读取命令行参数

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址