私はこの問題に対処しようとしていますが、あまり成功していません。いくつかの助けを願っています。
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);
}
}
これで終わりだと思います...申し訳ありません-コードが複雑であり、それが最初に簡略化されたバージョンのみを提供した理由です。うまくいけば、関連するすべての部分をリストしました