Java无法运行较大的Python文件。

huangapple go评论85阅读模式
英文:

Java Fails to Run Large Python Files

问题

我有一个Python脚本,我正在尝试通过Java代码来运行。

当我在我的Ubuntu虚拟机上使用与传递给Java脚本相同的命令通过Linux终端命令运行Python脚本时,Python脚本可以正常运行。

当运行一个比我尝试运行的Python脚本更快的不同Python脚本时,Java代码也可以正常运行。

然而,尽管Python脚本和Java脚本都能正常运行,但是当我将两者结合在一起时,什么都不会发生:.txt文件不会更新,因此Java脚本会打印出它包含的旧值。

以下是Java代码的一部分:

System.out.println("starting...");
try {
    Process process = Runtime.getRuntime().exec("python3 /home/.../PycharmProjects/.../fraudanalysis.py abc def");
    Thread.sleep(900000);
    // Or try System.out.println(process.waitFor());
    File file = new File("/home/.../PycharmProjects/.../output.txt");
    Scanner newLineReader = new Scanner(file);
    System.out.println(newLineReader.nextLine());
} catch(Exception e) {
    System.out.println(e);
}

上面的代码应该在提供的绝对目录中运行Python3脚本,使用两个参数。Python3脚本在大约13分钟后完成并更新output.txt文件,然后Java程序在等待15分钟后读取该文件(或者您可以告诉线程等待完成 - process.waitFor()返回1)。

以下是Python脚本的一部分:

def testScript():
    time.sleep(780)
    return_string1 = sys.argv[1]
    return_string2 = sys.argv[2]

    outputFile = open(os.path.dirname(os.path.abspath(__file__)) + "/output/output.txt", "w+")
    outputFile.write(return_string1 + " " + return_string2)
    print("Python run complete")

if __name__ == "__main__":
    testScript()

上面的脚本是Python脚本的一个良好替代品。如果将Python脚本的睡眠时间降低到10分钟,它将在Java发送命令时运行。但是,在上面显示的睡眠时间下,Java似乎无法运行脚本,或者脚本运行尝试以失败结束。

附加信息:Java命令是通过JavaFX按钮激活的。Java脚本是在IntelliJ IDEA中开发的,而Python脚本是使用PyCharm创建的。

我的问题是,当这两个脚本各自独立运行良好时,可能导致这个问题的可能原因是什么?

英文:

I have a Python script which I am attempting to run via code in Java.

The Python script runs fine when run through a Linux terminal command on my Ubuntu virtual machine using an identical command to the one being passed through the Java script.

The Java code runs fine when running a different Python script that runs faster than the Python script I'm attempting to run..

However, despite both the Python script running fine and the Java script running fine, somehow, when I put the two together, nothing happens: The .txt file isn't updated, so the Java script prints out whatever old value it contains.

System.out.println("starting...");
try {
    Process process = Runtime.getRuntime().exec("python3 /home/.../PycharmProjects/.../fraudanalysis.py abc def");
    Thread.sleep(900000);
    # Or try System.out.println(process.waitFor());
    File file = new File("/home/.../PycharmProjects/.../output.txt");
    Scanner newLineReader = new Scanner(file);
    System.out.println(newLineReader.nextLine());
} catch(Exception e) {
    System.out.println(e);
}

The code above should run the Python3 script at the absolute directory provided, using two arguments. The Python3 script completes after around 13 minutes and updates the output.txt file, which is then read by the Java program after waiting 15 minutes (or you can tell the thread to wait for completion-- process.WaitFor() returns 1).

def testScript():
    time.sleep(780)
    return_string1 = sys.argv[1]
    return_string2 = sys.argv[2]

    outputFile = open(os.path.dirname(os.path.abspath(__file__)) + "/output/output.txt", "w+")
    outputFile.write(return_string1 + " " + return_string2)
    print("Python run complete")

if __name__ == "__main__":
    testScript()

The script above is a good stand-in for the Python script. If you lower the sleep time to 10 minutes for the Python script, it runs when Java sends the command. But, at the sleep times shown above, Java apparently fails to run the script, or the script run attempt ends in failure.

Additional info: the Java command is activated using a JavaFX button. The Java script has been developed in IntelliJ IDEA and the Python script was created using PyCharm.

My question is, what are possible causes for this problem, when both scripts work fine on their own?

答案1

得分: 2

作为一个简单的建议,你不应该依赖于具有固定参数(如15分钟)的Thread.sleep方法。你的数据可能会增长或缩小,这种方式不高效。

你可以尝试调用Process.waitFor()方法,这样当Python进程结束时,你的线程会继续执行。

此外,你可以尝试使用ProcessBuilder,在处理有问题的系统执行情况时有时会有帮助。

以下是一些代码。在sub()中,你不能更改Python程序,但是为了使sub2()能够工作,你需要修改Python程序,使其输出在标准输出上,Java会将输出重定向到output.txt文件中。

public void sub() {
    System.out.println("正在开始...");
    Scanner newLineReader = null;
    try {
        Process process = Runtime.getRuntime().exec("python3 /home/.../PycharmProjects/.../fraudanalysis.py /home/.../PycharmProjects/.../fraudAnalysis.db 500");
        process.waitFor();
        File file = new File("/home/.../PycharmProjects/.../output.txt");
        newLineReader = new Scanner(file);
        String line;
        while((line=newLineReader.nextLine())!=null) {
            System.out.println(line);
        }
    } catch(IOException ioe) {
        ioe.printStackTrace();
    } catch(InterruptedException ie) {
        ie.printStackTrace();
    } finally {
        newLineReader.close();
    }
}

public void sub2() {
    ProcessBuilder pb =
       new ProcessBuilder("python3", 
               "/home/.../PycharmProjects/.../fraudanalysis.py", 
               "/home/.../PycharmProjects/.../fraudAnalysis.db", "500");

    File log = new File("/home/.../PycharmProjects/.../output.txt");
    pb.redirectErrorStream(true);
    pb.redirectOutput(Redirect.appendTo(log));
    Process p = null;
    try {
        p = pb.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        p.waitFor();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    Scanner newLineReader = null;
    try{
        newLineReader = new Scanner(log);
        String line;
        while((line=newLineReader.nextLine())!=null) {
            System.out.println(line);
        }
    } catch(IOException ioe) {
        ioe.printStackTrace();
    }
}
英文:

As a simple suggestion, you should not rely on Thread.sleep method with a fixed parameter such as 15 minutes. Your data may grow or shrink and that way of proceeding is not efficient.

You could try to call the Process.waitFor() method so that when the python process is over, your thread continues.

Moreover, you could try to use ProcessBuilder that sometimes helps when facing buggy System exec cases.

Here is some code. in sub(), you can not change the python program, but for sub2() to work, you have to modify the python program so that its output is on the standard out and Java would do the redirect to the output.txt file.

public void sub() {
System.out.println("startig...");
Scanner newLineReader = null;
try {
Process process = Runtime.getRuntime().exec("python3 /home/.../PycharmProjects/.../fraudanalysis.py /home/.../PycharmProjects/.../fraudAnalysis.db 500");
process.waitFor();
File file = new File("/home/.../PycharmProjects/.../output.txt");
newLineReader = new Scanner(file);
String line;
while((line=newLineReader.nextLine())!=null) {
System.out.println(line);
}
} catch(IOException ioe) {
ioe.printStackTrace();
}catch(InterruptedException ie) {
ie.printStackTrace();
}finally {
newLineReader.close();
}
}
public void sub2() {
ProcessBuilder pb =
new ProcessBuilder("python3", 
"/home/.../PycharmProjects/.../fraudanalysis.py", 
"/home/.../PycharmProjects/.../fraudAnalysis.db", "500");
File log = new File("/home/.../PycharmProjects/.../output.txt");
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Process p = null;
try {
p = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
try {
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
Scanner newLineReader = null;
try{
newLineReader = new Scanner(log);
String line;
while((line=newLineReader.nextLine())!=null) {
System.out.println(line);
}
}catch(IOException ioe) {
ioe.printStackTrace();
}
}

答案2

得分: 1

我进行了轻微的修改后,成功使其工作。我使用了相对文件位置和TimeUnit.MINUTES.sleep(15)。

package org.openjfx;

import java.io.File;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class TestWait {
    public static void main(String[] args) {
        System.out.println("starting...");
        String dir = "src/main/resources/org/openjfx/"; // python脚本的位置

        try {
            System.out.println("Working Directory = " + System.getProperty("user.dir"));
            //System.out.println("python3 " + dir + "fraudanalysis.py abc def");
            Process process = Runtime.getRuntime().exec("python3 " + dir + "fraudanalysis.py abc def");
            System.out.println(process.waitFor());
            TimeUnit.MINUTES.sleep(15);
            File file = new File("src/main/resources/org/openjfx/output.txt");
            Scanner newLineReader = new Scanner(file);
            System.out.println(newLineReader.nextLine());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

这是我使用的Python代码。

import sys
import time

def testScript():
    return_string1 = sys.argv[1]
    return_string2 = sys.argv[2]
    time.sleep(780)
    outputFile = open("src/main/resources/org/openjfx/output.txt", "w+")
    outputFile.write(return_string1 + " " + return_string2)
    print("Python run complete")

if __name__ == "__main__":
    testScript()
英文:

I was able to get it to work with a small modification. I used relative file locations and TimeUnit.MINUTES.sleep(15);

package org.openjfx;
import java.io.File;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class TestWait {
public static void main(String[] args) {
System.out.println("starting...");
String dir="src/main/resources/org/openjfx/";//location of the python script
try {
System.out.println("Working Directory = " + System.getProperty("user.dir"));
//System.out.println("python3 " + dir+"fraudanalysis.py abc def");
Process process = Runtime.getRuntime().exec("python3 " + dir+"fraudanalysis.py abc def");
System.out.println(process.waitFor());
TimeUnit.MINUTES.sleep(15);
File file = new File("src/main/resources/org/openjfx/output.txt");
Scanner newLineReader = new Scanner(file);
System.out.println(newLineReader.nextLine());
} catch (Exception e) {
System.out.println(e);
}
}
}

Here is the python I used.

import sys
import time
def testScript():
return_string1 = sys.argv[1]
return_string2 = sys.argv[2]
time.sleep(780)
outputFile = open("src/main/resources/org/openjfx/output.txt", "w+")
outputFile.write(return_string1 + " " + return_string2)
print("Python run complete")
if __name__ == "__main__":
testScript()

答案3

得分: -2

这是一个超时错误,无法修复。只需在Java和Python之间进行选择,并在其中一个语言中编写所有内容。没有理由同时使用两种语言。

英文:

it's a timeout error. can't be fixed. just pick between Java and Python and write everything in it. no reason to use both.

huangapple
  • 本文由 发表于 2020年8月20日 07:20:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63496238.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定