[英]Java subprocess built using ProcessBuilder looses data from serial port
我正在嘗試從Java應用程序內子進程中的串行端口讀取數據。 這是我當前正在使用的代碼:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Text {
public static void main(String... arguments) throws IOException, InterruptedException {
Process pb = new ProcessBuilder().command("/bin/sh", "-c", "(stty raw; cat) < /dev/ttyAMA0").start();
final Scanner scanner = new Scanner(new InputStreamReader(new BufferedInputStream(pb.getInputStream())));
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
});
t.start();
pb.waitFor();
}
}
這個想法是這樣的:我不會依賴操作系統(在Raspberry Pi上是Raspbian)從串行端口向我發送原始輸入。 因此,我啟動了一個子進程,該進程使用stty將串行端口設置為RAW模式,並使用cat轉發數據。 這個技巧在命令行上完美地起作用。 然后,如果我將stdout重定向到Java程序,數據將正確地流到其輸入流。
這里的問題是,使用此代碼將數據獲取到子進程(您猜不到它不是Java程序的標准輸入),我正在丟失字符。 我希望每行包含10個數字(由3個數字組成),並以逗號分隔,而我得到4到6個數字,有時后面跟一個逗號。
我認為有一個緩沖問題,我的Java應用程序可能無法清空(非常有限的)串行端口緩沖區。
有什么我可以做Java明智的選擇,還是應該轉向Linux內核極客尋求一些OS技巧?
謝謝,
馬修
嘗試在寫入后刷新,我想這就是您“松散”數據的原因:)
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
System.out.flush();
}
只是一個技巧,但是嘗試一下。 cat的stdout默認情況下是緩沖的,但是您想要的是未緩沖的stream。 嘗試更改該行:
(stty raw; cat) < /dev/ttyAMA0
至
(stty raw; cat -u) < /dev/ttyAMA0
好的,我使用來自那里的輸入使代碼正常工作: https : //unix.stackexchange.com/questions/40005/alternate-fifo-device-for-linux-with-a-way-bigger-buffer-while-still -有-fi
我們想要的是在(不是那么多字節)串行端口緩沖區和管道中的下一個命令之間有一個較大的緩沖區。 假設我希望包含82個字節的所有行,我使用buffer -s 82 -b 2
命令,該命令允許在每次掃描程序nextLine調用之間的共享內存中存儲一行的兩個塊。
這是完整的演示,它會使每個Raspberry Pi所有者嘗試讀取Java串行數據感到高興(我是唯一的嗎?):
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Text2 {
public static void main(String... arguments) throws IOException, InterruptedException {
Process pb = new ProcessBuilder().command("/bin/sh", "-c", "(stty raw; cat | buffer -s 82 -b 2) < /dev/ttyAMA0").start();
final Scanner scanner = new Scanner(new InputStreamReader(new BufferedInputStream(pb.getInputStream())));
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
});
t.start();
pb.waitFor();
}
}
這需要buffer
工具,可以輕松地鍵入sudo apt-get install buffer
這也依賴於一些技巧來啟用板載串行端口,如https://github.com/lurch/rpi-serial-console
感謝brettw帶來的投入,即使它最初並沒有奏效。
馬修
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.