1

私はこの問題に対処しようとしていますが、あまり成功していません。いくつかの助けを願っています。
Java プログラムの内部から、外部の実行可能ファイルを呼び出しています。これは、完了するとテキスト (ASCII) ファイルを作成します。私は使っている

Process p = Runtime.getRuntime().exec("....exe");`

次に、切り替える前に完了するように求めています

int exitValue = p.waitFor();

終了値が 0 であることを確認します。

その直後に、新しく作成されたファイルを読み取るための Scanner オブジェクトを作成しています。

File outputFile = new File(outputFileName);
Scanner scan = new Scanner(outputFile);

ファイルは実行可能ファイルと同じフォルダーにありますが、とにかくフルパスを渡しています。
ファイル ( ) を読み取れるかどうかを確認するとoutputFile.canRead()、答えは true です。
ファイルの長さを確認すると、0 より大きい数値、つまり 440827 が返されます。ただし、または
を呼び出そうとすると、答えは否定的です。 興味深いことに、これを NetBeans デバッグ モードで実行すると、すべて正常に動作します。したがって、プロセスのスレッドを中断しないように予防策を講じていますが、ある種の競合状態にあると思います。を呼び出す前にステートメントを挿入しようとしましたが、結果はありません。 何か提案はありますか?scan.hasNextLine()scan.hasNext()
Thread.sleep()nextLine()

これはコードの簡略化されたバージョンでした...リクエストに応じて、ここにより詳細な処理があります(4つのクラスに分散)-いくつかのレベルのリダイレクトについてお詫びします:

public class A
{
    private void runEngine()
    {
        try
        {
        // Skip irrelevant stuff - model is an object of class B:            
            model.runEngineIfNeeded(keepInputFiles);
            outputFileTextArea.setText(
                model.processOutput(keepInputFiles, keepOutputFiles));
        //...
        }
        catch (Throwable ex)
        {
            LOGGER.log(Level.SEVERE, null, ex);
        }
    }

public class B    
{
    public void runEngineIfNeeded(boolean keepInputFiles)
        throws IOException, InterruptedException
    {
        // exit under some condition, otherwise:
        boolean enginOK = false;

        while(!enginOK)             
             enginOK = createEnginFile(keepInputFiles);
    }
    public boolean createEnginFile(boolean keepFile)
    {
        String engineDir = "C:/data";     
        final String[] cmdArray = {"cmd", "/C", B.EXE_FILENAME};
        // output is a 2-dimensional array of strings
       output = Exec.getSTDERRandSTDOUT(cmdArray, engineDir);

       if (output[1].isEmpty())
            return true; //no exception occur

      // do some data manipulation and...
      return false;
    }

    public String processOutput(boolean keepLoopinInput, boolean keepLoopinOutputs)
                throws IOException, InterruptedException
   {
       String enginOutput = null;

       while (enginOutput == null)
       {
            enginOutput = c.processEnginOutput();  // c is an obj of class C

        if (enginOutput == null)
            createLoopinFile(keepEngineInput);
    }

    return enginOutput;
   }
}

public class Exec
{
    public static String[] getSTDERRandSTDOUT(String[] cmd, String directory)
        throws IOException, InterruptedException {
        String[] output = new String[2]; // 2 string array for output
        ProcessBuilder processBuilder = new ProcessBuilder(cmd);

        if (directory != null) {
            processBuilder.directory(new File(directory));
        }

        Process process = processBuilder.start();
        ExecStreamRedirect stdout = new ExecStreamRedirect(process.getInputStream(), 
                                                           OutputType.STDOUT);

       stdout.start();

       ExecStreamRedirect stderr = new ExecStreamRedirect(process.getErrorStream(),
                                                          OutputType.STDERR);

       stderr.start();
       int waitFor = process.waitFor();

       output[0] = stdout.getSTDOUT().toString();
       output[1] = stderr.getSTDERR().toString();
       return output;
    }
}

class C
{
    public String processEnginOutput(float actKtDLS, boolean keepOutputs)
                throws FileNotFoundException, InterruptedException,
                       IOException
    { // Read file into Output text area:
        File analysisOutputFile    = new File(outputFileNamePath);
        Scanner scan               = null;
        String scanLine            = "";
        StringBuilder enginOutput = new StringBuilder(
                                        (int) analysisOutputFile.length());
        boolean outputFileOK = false;

        // Must be careful here, possibility for endless loop:
        stop: for (int i = 2000; i < 4000 && !outputFileOK; i+= 100)
        {
            int j = 0; // start counting lines

            try
            {
                if (GenericUtils.waitIfFileIsNotReady(analysisOutputFile, j))
                 // does not exist & readable
                    continue; // go to next iteration

                scan = new Scanner(analysisOutputFile);

                for (; !outputFileOK; j++)
               {
                    scanLine = scan.nextLine();
                    enginOutput.append(scanLine).append("\n\n");

               // .. more logic here;
               }

               // .. more logic here;

               scan.close();

               return enginOutput.toString();
            } // end of try
            catch (NoSuchElementException ex)
            { //EOF reached
                 processEngineDelay(
             "output file is not completly written. Last line read: "
                                 + j + ".  " + scanLine +
                                  ". Wait " + i + " msecs.",
                                   scan,
                                   i);
            }  // continue [stop] with the next loop iteration...
        } // repeat up to 20 times if needed       
    }

    private static void processEngineDelay(String msg, Scanner scan, int i)
                throws InterruptedException
   {
        // to perform error processing
        LOGGER.warning(msg);
        scan.close(); // close scan
        scan = null;
        Thread.sleep(i);
   }
}

これで終わりだと思います...申し訳ありません-コードが複雑であり、それが最初に簡略化されたバージョンのみを提供した理由です。うまくいけば、関連するすべての部分をリストしました

4

0 に答える 0