簡體   English   中英

使用Java中的命令行-超時過程耗時太長

[英]Using the commandline from Java - timeout process that take too long

因此,我正在編寫一個程序來從Java運行命令行過程。 這需要在Windows和Linux上運行; 不過,我目前正在Windows 7上進行測試。我還應該提到#號之后的所有內容都被視為注釋。 這樣,這是我的代碼:

import java.io.*;
import java.util.*;

public class myShell
{
    public static void main(String[] args)
    {
        Runtime runtime = Runtime.getRuntime();
        Process process;
        Scanner keyboard = new Scanner(System.in);
        String userInput = "";
        String osName = System.getProperty("os.name" );
        BufferedReader brStdOut = null;
        String stdOut;
        String stdOutNextLine;
        BufferedReader brErrorStream = null;
        String errorStream;
        String errorStreamNextLine;

        while(userInput.compareToIgnoreCase("exit") != 0)
        {
            System.out.println();
            System.out.print("??");

            userInput = keyboard.nextLine();

            int indexOfPound = userInput.indexOf('#');
            if(indexOfPound == 0)
            {
                userInput = "";
            }
            else if(indexOfPound > 0)
            {
                userInput = userInput.substring(0, indexOfPound);
            }
            userInput = userInput.trim();

            try
            {   
                if(osName.contains("Windows"))
                {
                    process = runtime.exec("cmd /c " + userInput);
                }
                else
                {
                    process = runtime.exec(userInput);
                }

                brStdOut = new BufferedReader(new InputStreamReader(
                           process.getInputStream()));
                brErrorStream = new BufferedReader(new InputStreamReader(
                                process.getErrorStream()));

                stdOut = "";
                errorStream = "";
                boolean firstStdOut = true;
                boolean firstErrorStream = true;
                long time = System.currentTimeMillis();

                while(((stdOutNextLine = brStdOut.readLine())  != null) && 
                      ((System.currentTimeMillis() - time) < 5000))
                {
                    if(firstStdOut)
                    {
                        stdOut = stdOutNextLine;
                        firstStdOut = false;
                    }
                    else
                    {
                        stdOut = stdOut + "\n" + stdOutNextLine;
                    }
                }
                time = System.currentTimeMillis();
                while(((errorStreamNextLine = brErrorStream.readLine()) != null)
                      && ((System.currentTimeMillis() - time) < 5000))
                {
                    if(firstErrorStream)
                    {
                        errorStream = errorStreamNextLine;
                        firstErrorStream = false;
                    }
                    else
                    {
                        errorStream = errorStream + "\n" + errorStreamNextLine;
                    }
                }
                System.out.println(stdOut + errorStream);
            }
            catch(Exception e)
            {
                System.out.println("Error executing: " + userInput); 
                System.out.println(e.getMessage());
            }
            try
            {
                brStdOut.close();
            }
            catch(Exception e)
            {
            }
            try
            {
                brErrorStream.close();
            }
            catch(Exception e)
            {
            }
        }
        System.exit(0);
    }
}

因此,我遇到的問題是,當我在命令行中運行諸如date之類的命令時,會要求進一步的用戶輸入。 就目前而言,我只想使這些類型的命令超時,並獲得超時之前可以打印的所有內容。

因此,如果在命令行中日期將返回2行,然后等待用戶輸入,我只希望我的程序打印這2行,然后繼續。 問題是,按照編寫的方式,從命令行獲取輸出的while循環中的超時似乎沒有執行任何操作,無論是否有(System.currentTimeMillis()-time)<5000,程序運行的方式都完全相同限定詞。 我還嘗試將while循環編寫為:

while((stdOutNextLine = brStdOut.readLine())  != null)
{
    if(firstStdOut)
    {
        stdOut = stdOutNextLine;
        firstStdOut = false;
    }
    else
    {
        stdOut = stdOut + "\n" + stdOutNextLine;
    }
    if((System.currentTimeMillis() - time) > 5000)
    {
        throw new TimeoutException();
    }
}

然后從該處捕獲TimeoutException以與String一起使用,但這似乎實際上並未使進程超時。

還有其他想法嗎?

謝謝!

我建議您在此處閱讀問題和答案。 最好用ProcessBuilder代替Process。 另請參閱本文,以了解調用外部命令時的一些常見陷阱。

編輯:問題是readline方法被阻止,所以您的超時條件代碼永遠不會到達。 除非與NIO一起使用,否則不能對Java流使用超時。 一種實現方法是在主線程中發生超時時,產生一個用於讀取的線程並殺死它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM