Как работать с аргументами командной строки в Java - PullRequest
1 голос
/ 20 января 2012

Предположим, у меня есть простая программа, которая принимает аргументы в одной из следующих форм
do1 inputLocation outputLocation
do2 inputLocation outputLocation
do3 [30 или 60 или 90] inputLocation outputLocation
do4 [P D или C] inputLocation outputLocation
do5 [G H I] inputLocation outputLocation

У меня также есть 5 функций с одинаковыми именами в программе, которую мне нужно вызвать. До сих пор я думал о том, чтобы сделать это таким образом (в «полупсевдокоде»)

static void main(String[] args)
{
    if (args.length == 3)
        processTriple(args);
    if (args.length == 4)
        processQuadruple(args);
    throw new UnsupportedOperationException("dasdhklasdha");
}

где функции процесса выглядят так

processDouble(String args[])
{
    String operation = "args[0]";
    Location input = getInput(args[1]);
    Location output = getInput(args[2]);
    if (operation.equals("do1"))
        do1(input,output);
    if (operation.equals("do2"))
        do2(input,output);
    ... etc
}

То, как я это делаю, кажется не очень расширяемым. Если аргументы функции изменяются или добавляются новые функции, кажется, что это было бы трудно поддерживать. Какой самый лучший способ сделать что-то вроде этого

Ответы [ 5 ]

10 голосов
/ 20 января 2012

на этом этапе я бы использовал commons-cli или jargs . Если вы не пытаетесь сделать что-то действительно особенное с аргументами, я бы сказал, сосредоточьтесь на реальном бизнесе вашего приложения, а не разбирайтесь в беспорядке аргументов приложения

3 голосов
/ 20 января 2012

Использовать библиотеку анализа строки комманда. Взгляните на здесь .

2 голосов
/ 20 января 2012

Я использовал JOpt Simple в прошлом с отличными результатами.Это позволяет вам абстрагироваться от аргумента командной строки и поддерживать действительно чистый обновляемый список аргументов.Дополнительным преимуществом является то, что он сгенерирует вывод справки, который имеют стандартные утилиты командной строки.

Вот краткий пример:

private void runWithArgs (String[] args) {
    OptionParser parser = getOptionParser ();
    OptionSet options = null;

    try {
        options = parser.parse (args);
    }
    catch (OptionException e) {
        log.error ("Sorry the command line option(s): " + e.options () + 
                    " is/are not recognized. -h for help.");
        return;
    }

    if (options.has ("h")) {
        try {
            log.info ("Help: ");
            parser.printHelpOn (System.out);
        }
        catch (IOException e) {
            log.error ("Trying to print the help screen." + e.toString ());
        }
        return;
    }

    if (options.has ("i")) {
        defaultHost = (String) options.valueOf ("i");
    }

    if (options.has ("p")) {
        defaultPort = (Integer) options.valueOf ("p");
    }

    if (options.has ("q")) {
        String queryString = (String) options.valueOf ("q");

        log.info ("Performing Query: " + queryString);
        performQuery (queryString, defaultHost, defaultPort);
        return;
    }
}
1 голос
/ 21 января 2012

Вы можете использовать библиотеку Седрика Беуста JCommander

Поскольку жизнь слишком коротка для разбора параметров командной строки

Я даже творчески нарушаю первоначальное намерение библиотеки разобрать предложения NMEA 0183, например $ GPRTE , следующим образом:

import java.util.List;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.internal.Lists;

public class GPRTE {
    @Parameter
    public List<String> parameters = Lists.newArrayList();

    @Parameter(names = "-GPRTE", arity = 4, description = "GPRTE")
    public List<String> gprte;
}

Фрагмент кода, который обрабатывает предложение NMEA 0183 $ GPRTE из $GPRTE,1,1,c,*37 в -GPRTE 1 1 c *37 для соответствия синтаксическому синтаксическому разбору JCommander:

/**
 * <b>RTE</b> - route message<p>
 * Processes each <b>RTE</b> message received from the serial port in following format:<p>$GPRTE,d1,d2,d3,d4<p>Example: $GPRTE,1,1,c,*37
 * @param sequences result of {@link #Utils.process(String)} method
 * @see <a href="http://www.gpsinformation.org/dale/nmea.htm#RTE">http://www.gpsinformation.org/dale/nmea.htm#RTE<a><p>*/
public static void processGPRTE(final String command){
    final String NMEA_SENTENCE = "GPRTE";
    final String PARAM = "\u0001";
    final String DOLLAR = "\u0004";
    final String COMMA = "\u0005";

    String parsedString = command;

    if (parsedString.contains("$"+NMEA_SENTENCE)){

        parsedString = parsedString.replaceAll("\\$", DOLLAR+PARAM);
        parsedString = parsedString.replaceAll(",", COMMA);

        System.out.println("GPRTE: " + parsedString);

        String[] splits = parsedString.split(DOLLAR);
        for(String info: splits){

            if (info.contains(PARAM+NMEA_SENTENCE)) {
                info = info.replaceFirst(PARAM, "-");

                System.out.println("GPRTE info: " + info);


                String[] args = info.split(COMMA);

                GPRTE cmd = new GPRTE();
                new JCommander(cmd, processEmptyString(args));
                List<String> message = cmd.gprte;

                String data1 = SerialOutils.unescape(message.get(0));
                System.out.println("GPRTE: data1 = " + data1);

                String data2 = SerialOutils.unescape(message.get(1));
                System.out.println("GPRTE: data2 = " + data2);

                String data3 = SerialOutils.unescape(message.get(2));
                System.out.println("GPRTE: data3 = " + data3);

                String data4 = SerialOutils.unescape(message.get(3));
                System.out.println("GPRTE: data4 = " + data4);

                System.out.println("");

            }
        }
    }
}
1 голос
/ 20 января 2012

Я уже использовал args4j с успешными результатами и раньше.

Просто еще один вариант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...