命令行交互的一种Java实现

    现在服务器远程控制一般都是web方式实现的,这种方式体现的最明显的是J2EE应用服务器;当然为了操作方便,有些服务器也提供GUI客户端,
不过笔者比较喜欢字符终端,我想有很多人同笔者一样,在这里,向大家介绍一个Java实现的命令行程序,这是笔者当时阅读OBE(一个Workflow Engine)
的源代码时的收获,把代码调整了一下,版权就不属于Adrian.Price的了,哈哈!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class CommandClient {

    //返回菜单
    protected static final Object[] BACK = {"Q", "Back to previous menu", null};
    protected static final String UNDERLINE = "-----------------------------------------------------------------------------";
   
    //设置菜单
    private static final Object[][] SET_MENU = {
        // mnemonic, description, method
        {"1", "Load Default value", "loadDefault"},
        {"2", "Set Remote Host and Port(example,localhost:8191)", "setHost"},
        {"3", "Set Welcome message", "setMessage"},
        BACK
    };
  //主菜单 
 private static final Object[][] MAIN_MENU = {
        // mnemonic, description, method
        {"1", "Set", SET_MENU},
        {"2", "Check Server Status", "checkServerStatus"},
        {"3", "Shutdown Server", "shutdownServer"},
        {"Q", "Quit", "quit"}
    };
 
 protected BufferedReader _stdin;
    protected FormattingPrintWriter _stdout;
    protected String title = null;

   
    public void setHost()
     throws IOException
    {
     System.out.println("please enter connection string:");
     BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
     System.out.println("The host you set is " + stdin.readLine());
    }
    public void shutdownServer()
    {
     System.out.println("server has been shut down");
    }
    public void checkServerStatus()
    {
     System.out.println("server is OK");
    }
    public CommandClient()
    {
     _stdin = new BufferedReader(new InputStreamReader(System.in));
        _stdout = new FormattingPrintWriter(System.out, true);
        title = "Command Client";
        _stdout.println("\n--- "+title+"  ---");
    }
    protected void quit() {
        System.exit(0);
    }
    private Method findMethod(String name) {
        Class cl = getClass();
        Method method = null;
        while (method == null) {
            try {
                method = cl.getDeclaredMethod(name, null);
            } catch (NoSuchMethodException e) {
                System.out.println("no method define");
                cl = cl.getSuperclass();
                if (cl == null) {
                    e.printStackTrace();
                    System.exit(1);
                }
             /*
                try
             {
              return cl.getDeclaredMethod("done", null);
             }
                catch (NoSuchMethodException ex) {ex.printStackTrace();}
                */
            }
        }
        return method;
    }
    protected String getChoice(String choices)
     throws IOException {
        while (true) {
            _stdout.print("> ");
            _stdout.flush();
            String line = _stdin.readLine().trim();
            if (line.length() == 1) {
                int choice = Character.toUpperCase(line.charAt(0));
                int index = choices.indexOf(choice);
                if (index != -1)
                    return choices.substring(index, index + 1);
            }
            _stdout.println("\007*** Choice must be one of: " + choices);
        }
    }
    //选择菜单选项,动态调用某个方法
    public void doMenu(Object[][] menu, boolean main)
    {
     this.doMenu(this.title,menu,main);
    }
    public void doMenu(String pTitle,Object[][] menu, boolean main)
    {
        synchronized (System.in) {
            Map actions = new HashMap();
            StringBuffer sb = new StringBuffer(menu.length);
            for (int i = 0; i < menu.length; i++) {
                Object mnemonic = menu[i][0];
                sb.append(mnemonic);
                Object action = menu[i][2];
                if (action instanceof String)
                    action = findMethod((String)action);
                actions.put(mnemonic, action);
            }
            String choices = sb.toString();

            while (true) {/
                try {
                    String mnemonic;

                    _stdout.clearTabs();
                    _stdout.println("\n---   " + pTitle + "   ---");
                    _stdout.println("\nEnter choice:");
                    for (int i = 0; i < menu.length; i++)
                        _stdout.println(menu[i][0] + ") " + menu[i][1]);

                    // Get the user's selection.
                    mnemonic = getChoice(choices);
                    //System.out.println("mnemonic="+mnemonic);
                    for (int i = 0; i < menu.length; i++) {
                        Object[] entry = menu[i];
                        if (entry[0].equals(mnemonic)) {
                            Object action = actions.get(mnemonic);
                            if (action == null) {
                                return;
                            } else if (action instanceof Method) {
                                //System.out.println("selected,will do");
                                // Cast required to suppress JDK1.5 varargs compiler warning.
                                ((Method)action).invoke(this, (Object[])null);
                            } else {
                                doMenu((String)entry[1], (Object[][])action,
                                    false);
                            }
                        }
                    }
                } catch (Exception e) {
                    Throwable t = e;
                    if (e instanceof InvocationTargetException)
                        t = ((InvocationTargetException)e).getTargetException();
                    _stdout.println("\007*** Caught exception: " + t);
                }
            }
        }
    }
 /**
  * @param args
  */
 public static void main(String[] args)
 {
  new CommandClient().doMenu(MAIN_MENU,true);
 }
 public void setMessage()
  throws IOException
 {
  System.out.println("please enter welcome message:");
     BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
     System.out.println("welcome message  is " + stdin.readLine());
 }
 public void loadDefault()
 {
  System.out.println("default setting is loaded");
 }

}

附另外一个类(javaeye的blog有点令我失望,加个附件也很痛苦)

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Stack;

/**
 * A PrintWriter class that supports tab stops and programmable indentation.
 * The writer interprets tab characters in the usual way, by emitting spaces to
 * align the following characters at the next tab stop to the right of the
 * current print position. The default tab stops are at every 8 characters,
 * that is, in columns 9, 17, 25, ... 81. The {@link #setTabs} method allows
 * custom tab stops to be specified. Indentation can be controlled via the
 * {@link #pushIndent()}, {@link #pushIndent(int)} and {@link #popIndent()}
 * methods.
 *


 * The writer scans all arguments for newline characters, and achieves the
 * desired indentation level by inserting a corresponding number of spaces into
 * the output before continuing with the characters following the newline.
 * Indentation settings are held internally on a stack so that cancelling the
 * current setting automatically restores the previous one.
 *
 * @author Adrian Price
 */
public class FormattingPrintWriter extends PrintWriter {
    private static final String NEWLINE =
        System.getProperty("line.separator", "\r\n");
    // Standard tab settings
    private static final int[] STD_TABS =
        {9, 17, 25, 33, 41, 49, 57, 65, 73, 81};

    private boolean _autoFlush;
    private int[] _tabs = STD_TABS;
    private Stack _stack = new Stack();
    private int _indent;
    private int _pos;

    /**
     * Returns a string consisting of the specified number of spaces.
     *
     * @return The requested whitespace string.
     */
    private static String spaces(int n) {
        char[] ca = new char[n];
        for (int i = 0; i < n; i++)
            ca[i] = ' ';
        return new String(ca, 0, ca.length);
    }

    /**
     * Constructs a new FormattingPrintWriter, without automatic line flushing.
     *
     * @param out A character-output stream.
     */
    public FormattingPrintWriter(Writer out) {
        super(out);
    }

    /**
     * Constructs a new FormattingPrintWriter.
     *
     * @param out       A character-output stream.
     * @param autoFlush If true, the println() methods will flush
     *                  the output buffer.
     */
    public FormattingPrintWriter(Writer out, boolean autoFlush) {
        super(out, autoFlush);
        _autoFlush = autoFlush;
    }

    /**
     * Constructs a new PrintWriter, without automatic line flushing, from an
     * existing OutputStream. This convenience constructor creates the necessary
     * intermediate OutputStreamWriter, which will convert characters into bytes
     * using the default character encoding.
     *
     * @param out An output stream.
     */
    public FormattingPrintWriter(OutputStream out) {
        super(out);
    }

    /**
     * Constructs a new PrintWriter from an existing OutputStream. This
     * convenience constructor creates the necessary intermediate
     * OutputStreamWriter, which will convert characters into bytes using the
     * default character encoding.
     *
     * @param out       An output stream.
     * @param autoFlush if true, the println() methods will flush
     *                  the output buffer.
     */
    public FormattingPrintWriter(OutputStream out, boolean autoFlush) {
        super(out, autoFlush);
        _autoFlush = autoFlush;
    }

    /**
     * Restores the default tab stops.
     */
    public void clearTabs() {
        setTabs(null);
    }

    /**
     * Sets custom tab stops. At output positions past the rightmost tab stop,
     * tab characters are converted into single spaces.
     *
     * @param tabs Unity-based tab stop positions, as an ascending sequence of
     *             positive integers.
     */
    public void setTabs(int[] tabs) {
        synchronized (lock) {
            if (tabs == null) {
                _tabs = STD_TABS;
            } else {
                for (int i = 0, n = tabs.length - 1; i < n; i++) {
                    if (tabs[i] <= 0 || tabs[i] >= tabs[i + 1])
                        throw new IllegalArgumentException(
                            "Tab stops must be an ascending sequence of positive integers.");
                }
                _tabs = new int[tabs.length];
                System.arraycopy(tabs, 0, _tabs, 0, tabs.length);
            }
            if (_pos != 0)
                println();
        }
    }

    /**
     * Returns unity-based tab stop positions, as an ascending sequence of
     * positive integers.
     *
     * @return Current tab stops.
     */
    public int[] getTabs() {
        return (int[])_tabs.clone();
    }

    /**
     * Increases the indentation level by the specified amount.
     *
     * @param i Number of columns by which to increase indentation.
     */
    public void pushIndent(int i) {
        if (i <= 0) {
            throw new IllegalArgumentException(
                "Indentation must be a positive integer");
        }
        synchronized (lock) {
            _stack.push(new Integer(i));
            _indent += i;
        }
    }

    /**
     * Increases the indentation level to the next tab stop past the current
     * output position.
     */
    public void pushIndent() {
        // Indent to the nearest tab stop to the right of the current
        // indentation level, if such a tab stop exists.
        for (int i = 0, n = _tabs.length; i < n; i++)
            if (_tabs[i] > _indent) {
                pushIndent(_tabs[i] - _indent);
                return;
            }
        // Past the rightmost tab stop, indentation is one space.
        pushIndent(1);
    }

    /**
     * Restores the previous indentation level.
     *
     * @throws IllegalStateException if the current indentation level is 0.
     */
    public void popIndent() {
        if (_stack.empty())
            throw new IllegalStateException();
        _indent -= ((Integer)_stack.pop()).intValue();
    }

    /**
     * Returns the current indentation level.
     *
     * @return Indentation level as a character count.
     */
    public int getIndent() {
        return _indent;
    }

    /**
     * Returns the current output position (zero-based).
     *
     * @return The output position.
     */
    public int getPosition() {
        return _pos;
    }

    /**
     * Expands a tab character by setting the output position to the next tab
     * stop past the current output position.
     *
     * @return Space-filled string.
     */
    private String expandTab() {
        // If pos is after the last tab stop, translate tab characters to spaces.
        String s = " ";
        int curpos = _indent + _pos;
        for (int i = 0; i < _tabs.length; i++) {
            // Tab stops use 1-based column numbers,
            if (_tabs[i] - 1 > curpos) {
                // curpos is a 0-based column index.
                s = spaces(_tabs[i] - curpos - 1);
                break;
            }
        }
        _pos += s.length();
        return s;
    }

    /**
     * Expands embedded tab and newline escape sequences, adjusting the output
     * position accordingly. The method recognizes 'C'/Java-style '\t', '\r' and
     * '\n' escape sequences.
     *
     * @param ch Character to expand.
     * @return String containing (expanded) input character.
     */
    private String expandEscapes(char ch) {
        StringBuffer result = new StringBuffer();
        switch (ch) {
            case '\t':
                if (_pos == 0 && _indent > 0)
                    result.append(spaces(_indent));
                result.append(expandTab());
                break;
            case '\n':
                _pos = 0;
            case '\r':
                result.append(ch);
                break;
            default:
                if (_pos == 0 && _indent > 0)
                    result.append(spaces(_indent));
                result.append(ch);
                _pos++;
        }
        return result.toString();
    }

    /**
     * Expands embedded tab and newline escape sequences, adjusting the output
     * position accordingly. The method recognizes 'C'/Java-style '\t', '\r' and
     * '\n' escape sequences.
     *
     * @param s   Source string.
     * @param off Offset at which to start copying.
     * @param len Number of source characters to process.
     * @return Copy of the source string where all escape sequences have been
     *         replaced by their equivalent characters.
     */
    private String expandEscapes(String s, int off, int len) {
        StringBuffer result = new StringBuffer(len);
        for (int i = off, end = off + len; i < end; i++) {
            char ch = s.charAt(i);
            switch (ch) {
                case '\t':
                    if (_pos == 0 && _indent > 0)
                        result.append(spaces(_indent));
                    result.append(expandTab());
                    break;
                case '\n':
                    _pos = 0;
                case '\r':
                    result.append(ch);
                    break;
                default:
                    if (_pos == 0 && _indent > 0)
                        result.append(spaces(_indent));
                    result.append(ch);
                    _pos++;
            }
        }
        return result.toString();
    }

    /**
     * Writes a character, which may be a tab or newline.
     *
     * @param c Character to write.
     */
    private void _writeEx(int c) {
        String s = expandEscapes((char)c);
        super.write(s, 0, s.length());
    }

    /**
     * Writes a string which may contain tab or newline characters.
     *
     * @param s   Source string.
     * @param off Offset at which to start writing.
     * @param len Number of source characters to process.
     */
    private void _writeEx(String s, int off, int len) {
        s = expandEscapes(s, off, len);
        super.write(s, 0, s.length());
    }

    /**
     * Writes a string that does not contain embedded tabs or newlines.
     *
     * @param s   Source string.
     * @param off Offset at which to start writing.
     * @param len Number of source characters to process.
     */
    private void _write(String s, int off, int len) {
        _pos += len;
        super.write(s, off, len);
    }

    public void print(boolean b) {
        String s = String.valueOf(b);
        _write(s, 0, s.length());
    }

    public void print(char c) {
        _writeEx(c);
    }

    public void print(int i) {
        String s = String.valueOf(i);
        _write(s, 0, s.length());
    }

    public void print(long l) {
        String s = String.valueOf(l);
        _write(s, 0, s.length());
    }

    public void print(float f) {
        String s = String.valueOf(f);
        _write(s, 0, s.length());
    }

    public void print(double d) {
        String s = String.valueOf(d);
        _write(s, 0, s.length());
    }

    public void print(char[] ca) {
        _writeEx(new String(ca), 0, ca.length);
    }

    public void print(String s) {
        _writeEx(s, 0, s.length());
    }

    public void print(Object obj) {
        String s = String.valueOf(obj);
        _writeEx(s, 0, s.length());
    }

    private void newLine() {
        _write(NEWLINE, 0, NEWLINE.length());
        _pos = 0;
        if (_autoFlush)
            flush();
    }

    public void println() {
        synchronized (lock) {
            newLine();
        }
    }

    public void println(boolean b) {
        synchronized (lock) {
            print(b);
            newLine();
        }
    }

    public void println(char c) {
        synchronized (lock) {
            print(c);
            newLine();
        }
    }

    public void println(int i) {
        synchronized (lock) {
            print(i);
            newLine();
        }
    }

    public void println(long l) {
        synchronized (lock) {
            print(l);
            newLine();
        }
    }

    public void println(float f) {
        synchronized (lock) {
            print(f);
            newLine();
        }
    }

    public void println(double d) {
        synchronized (lock) {
            print(d);
            newLine();
        }
    }

    public void println(char[] c) {
        synchronized (lock) {
            print(c);
            newLine();
        }
    }

    public void println(String s) {
        synchronized (lock) {
            print(s);
            newLine();
        }
    }

    public void println(Object obj) {
        synchronized (lock) {
            print(obj);
            newLine();
        }
    }

    public void write(int c) {
        _writeEx(c);
    }

    public void write(char[] buf, int off, int len) {
        _writeEx(new String(buf, off, len), 0, len);
    }

    public void write(char[] buf) {
        _writeEx(new String(buf), 0, buf.length);
    }

    public void write(String s, int off, int len) {
        _writeEx(s, off, len);
    }

    public void write(String s) {
        _writeEx(s, 0, s.length());
    }
    public static void main(String[] args)
     throws Exception
    {
     System.out.println("please enter file path");
     BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
     String line = null;
     while ((line = stdin.readLine()) != null)
     {
      File dir = new File(line.trim());
      if (dir.exists())
      {
       System.out.println(dir.getAbsolutePath());
       break;
      }
      else
      {
       System.out.println("dir does not exist,please re-enter:");
      }
     }
    }
}


你可能感兴趣的:(命令行交互的一种Java实现)