欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

【Java基础】Java与Windows系统的交互,

来源: javaer 分享于  点击 22032 次 点评:133

【Java基础】Java与Windows系统的交互,


作者:郭嘉
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell

一 Java执行CMD命令

原理

Process process = Runtime.getRuntime().exec("cmd order");
  • cmd /c cmdorder 是执行完cmdorder命令后关闭命令窗口。
  • cmd /k cmdorder 是执行完cmdorder命令后不关闭命令窗口。
  • cmd /c start cmdorder 会打开一个新窗口后执行cmdorder指令,原窗口会关闭。
  • cmd /k start cmdorder 会打开一个新窗口后执行cmdorder指令,原窗口不会关闭。

注意

如果exec()中只有CMD命令,则命令会直接被执行,而不会打开命令行窗口;

举例

下面例子实现了执行解压JAR包,并把命令行信息输到Java的图形界面的功能:

Process process = null;
try
{
    process = Runtime.getRuntime().exec("jar xvf " + jarInputFile.getPath()) ;
}
catch (IOException e)
{
    e.printStackTrace();
}

InputStream inputStream = process.getInputStream();
Reader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
try
{
    for(String s = ""; ( s = bufferedReader.readLine()) != null;)
    {
        consoleInfo.append(s + "<br>");
    }
        bufferedReader.close();
        reader.close();
        JLabel consoleLabel = new JLabel();
        consoleLabel.setText("<html>" + consoleInfo.toString() + "</html>");
    }
}
catch (/ e)
{
    e.printStackTrace();
}

注意:Java Swing的文字显示不支持直接“\n”换行,所以使用“”标签的形式来实现换行。

二 CMD输出信息重定向

以上程序展示的是把执行一条命令后,把命令行上的信息输出到Java的图形界面上,那么如何实现实时的检测Windows的命令行打印信息并进行输出呢?

实现方法

Java的System类中有个out成员变量,称为标准输出流,用来把打印输出到屏幕上。上面所述的问题其实就是System.out的输出重定向问题。

System.out在Java中源码实现如下所示:

    /**
     * Default input stream.
     */
    public static final InputStream in;

    /**
     * Default output stream.
     */
    public static final PrintStream out;

    /**
     * Default error output stream.
     */
    public static final PrintStream err;

    private static final String lineSeparator;
    private static Properties systemProperties;

    static {
        err = new PrintStream(new FileOutputStream(FileDescriptor.err));
        out = new PrintStream(new FileOutputStream(FileDescriptor.out));
        in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
        lineSeparator = System.getProperty("line.separator");
    }

从上面可以看出,System.out是一个PrintStream。只需要把它重定向到我们需要的地方就可以了,具体代码实现如下所示:

package com.allenwells.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class ConsolePane extends JScrollPane
{

    private static final long serialVersionUID = 1L;

    private JTextPane textPane = new JTextPane();

    private static ConsolePane console = null;

    public static synchronized ConsolePane getInstance()
    {
        if (console == null)
        {
            console = new ConsolePane();
        }
        return console;
    }

    private ConsolePane()
    {

        setViewportView(textPane);

        // Set up System.out
        PrintStream mySystemOut = new MyPrintStream(System.out, Color.black);
        System.setOut(mySystemOut);

        // Set up System.err
        PrintStream mySystemErr = new MyPrintStream(System.err, Color.red);
        System.setErr(mySystemErr);

        textPane.setEditable(true);
        setPreferredSize(new Dimension(640, 120));
    }

    /**
     * Returns the number of lines in the document.
     */
    private final int getLineCount()
    {
        return textPane.getDocument().getDefaultRootElement().getElementCount();
    }

    /**
     * Returns the start offset of the specified line.
     * 
     * @param line
     *            The line
     * @return The start offset of the specified line, or -1 if the line is
     *         invalid
     */
    private int getLineStartOffset(int line)
    {
        Element lineElement = textPane.getDocument().getDefaultRootElement()
                .getElement(line);
        if (lineElement == null)
            return -1;
        else
            return lineElement.getStartOffset();
    }

    /**
     * 清除超过行数时前面多出行的字符
     */
    private void replaceRange(String str, int start, int end)
    {
        if (end < start)
        {
            throw new IllegalArgumentException("end before start");
        }
        Document doc = textPane.getDocument();
        if (doc != null)
        {
            try
            {
                if (doc instanceof AbstractDocument)
                {
                    ((AbstractDocument) doc).replace(start, end - start, str,
                            null);
                }
                else
                {
                    doc.remove(start, end - start);
                    doc.insertString(start, str, null);
                }
            }
            catch (BadLocationException e)
            {
                throw new IllegalArgumentException(e.getMessage());
            }
        }
    }

    class MyPrintStream extends PrintStream
    {

        private Color foreground; // 输出时所用字体颜色

        /**
         * 构造自己的 PrintStream
         * 
         * @param out
         *            可传入 System.out 或 System.err, 实际不起作用
         * @param foreground
         *            显示字体颜色
         */
        MyPrintStream(OutputStream out, Color foreground)
        {
            super(out, true); // 使用自动刷新
            this.foreground = foreground;
        }

        /**
         * 在这里重截,所有的打印方法都要调用最底一层的方法
         */
        public void write(byte[] buf, int off, int len)
        {
            final String message = new String(buf, off, len);

            /** SWING非界面线程访问组件的方式 */
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    try
                    {

                        StyledDocument doc = (StyledDocument) textPane
                                .getDocument();

                        // Create a style object and then set the style
                        // attributes
                        Style style = doc.addStyle("StyleName", null);

                        // Foreground color
                        StyleConstants.setForeground(style, foreground);

                        doc.insertString(doc.getLength(), message, style);

                    }
                    catch (BadLocationException e)
                    {
                        // e.printStackTrace();
                    }

                    // Make sure the last line is always visible
                    textPane.setCaretPosition(textPane.getDocument()
                            .getLength());

                    // Keep the text area down to a certain line count
                    int idealLine = 150;
                    int maxExcess = 50;

                    int excess = getLineCount() - idealLine;
                    if (excess >= maxExcess)
                    {
                        replaceRange("", 0, getLineStartOffset(excess));
                    }
                }
            });
        }
    }

}

使用方法

JPanel contentPanel = new JPanel();
ConsolePane consolePane = ConsolePane.getInstance();
contentPanel.add(consolePane);

效果图如下所示:

附录:

这里给出常见的CMD命令:

相关文章

    暂无相关文章
相关栏目:

用户点评