Я пытаюсь организовать скрипты Python на малиновой Pi через Java-программу. У меня есть код Python с бесконечным циклом внутри, который считывает расстояние от ультразвукового датчика и выводит его на консоль. Код Java вызывает это как процесс оболочки, а затем считывает процесс OutputStream. Проблема, которую я испытываю, заключается в том, что данные поступают большими партиями. Вместо того чтобы я получал новое значение каждый раз, когда скрипт Python выводится на консоль, я получаю новые данные каждые 10 секунд или около того. Это проблематично, потому что я пытаюсь отобразить данные на веб-панели в режиме почти в реальном времени.Чтение из Java InputStream, сгенерированное скриптом оболочки, происходит в пакетах
Диаграмма будет выглядеть следующим образом:
DistanceController
|--getDistance(public)
|--getBufferSize(public)
|--buffer(private)
|--DistanceThread(private)
|--bufferReference (private)
|--PythonScriptProcess
код Java выглядит следующим образом:
Это класс-оболочка, которая создает новый поток (отдельный класс) для чтения из потока вывода скрипта Python.
public class DistanceController {
private DistanceThread distanceThread;
private Thread t;
private LinkedList<DistanceVT> buffer = new LinkedList<DistanceVT>();
public DistanceController()
{
t = new Thread(distanceThread);
t.start();
}
public DistanceVT getDistance() {
return buffer.getLast();
}
}
Это нить, которая читает расстояние, идея состоит в том, чтобы она была неблокирующей.
public class DistanceThread implements Runnable {
private LinkedList<DistanceVT> buffer;
private String[] args = new String[]{"python", "./run-scripts/distance.py"};
public DistanceThread(LinkedList<DistanceVT> list) {buffer = list;}
@Override
public void run() {
while (true) {
try {
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
final Process p = pb.start();
while (true) {
InputStream s = p.getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(s));
while (((line = reader.readLine()) != null)) {
buffer.add(parseDistance(line));
}
}
} catch (Exception e) {
//handle errors
}
}
}
И код Python выглядит так (слегка измененный вариант простейшего кода измерения расстояния):
import time
import datetime
from random import randint
def measure_distance():
time.sleep(0.1)
return randint(10,15)
while True:
distance = measure_distance()
print ("%s,%s" % (datetime.datetime.now(),distance))
Можете ли вы уменьшить код, необходимый для абсолютного минимума, для воспроизведения проблемы? –
Конечно, Джим, я отредактирую свой оригинальный вопрос? –
Процесс, производящий выход, буферизует его. Вы ничего не можете сделать в коде Java. Исправьте код Python. NB Нет чтения нитей из 'Reader' или' InputStream', возможно, не блокируется. Также совершенно непонятно, почему буферизация имеет значение, когда поток чтения только накапливает вывод в списке. – EJP