J'ai un processus ProcessBuilder exécuté avec succès qui scanne un DVB-T pour les diffusions de chaînes sur un serveur et je veux que la sortie se passe sur une page Web.Java ProcessBuilder comment récupérer la sortie en direct
Le code du serveur comme suit:
private static StringBuilder scan_output = null;
private static String scan_result = "";
@Override
public boolean scanByBroadcaster(String user, String broadcaster) {
UserAccountPermissions perm = validateUserEdit(user); // allowed to run scan?
if (perm == null) return false;
String[] commands = {
"/usr/bin/scan",
dvbDir + broadcaster,
"-o",
"zap",
"-U",
"-q",
"-a",
"5",
">",
LoginConstants.loc_dvb_scanfile
};
System.out.println("Scan by broadcast: " + broadcaster);
scan_output = new StringBuilder();
new ScanThread(commands).start();
return false;
}
// runs the scan independant and the IO capture
private static class ScanThread extends Thread {
String[] commands = null;
public ScanThread(String[] commands) {
this.commands = commands;
}
public void run() {
ProcessBuilder pb = new ProcessBuilder(commands);
Process process;
try {
System.out.println("Scan thread running");
process = pb.start();
IOScanOutputHandler handler = new IOScanOutputHandler(process.getInputStream());
handler.start();
process.waitFor();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
//scan_output = null;
System.out.println("Scan thread finished");
}
}
// background thread to capture output of scan (as it arrives)
// this only captures the final scan results though
private static class IOScanOutputHandler extends Thread {
private InputStream inputStream;
IOScanOutputHandler(InputStream inputStream) {
this.inputStream = inputStream;
}
public void run() {
Scanner br = null;
try {
System.out.println("Scan thread IO capture running");
br = new Scanner(new InputStreamReader(inputStream));
String line = null;
while (br.hasNextLine()) {
line = br.nextLine();
scan_output.append(line + System.getProperty("line.separator"));
}
} finally {
br.close();
}
System.out.println("Scan thread IO capture finished");
scan_result = scan_output.toString();
scan_output = null;
}
}
// polled by web interface every second
@Override
public String pollScanResult(String user) {
if (validateUserEdit(user) == null) return null;
StringBuilder sb = scan_output; // grab instance
if (sb == null) return null;
return sb.toString();
}
La sortie finale, je reçois en fait est ce qui se passe dans « LoginConstants.loc_dvb_scanfile » et non cette sortie:
ERROR: invalid enum value '7378'
ERROR: invalid enum value '3300'
ERROR: invalid enum value '0'
ERROR: invalid enum value '8MHz'
ERROR: invalid enum value '2/3'
ERROR: invalid enum value 'NONE'
ERROR: invalid enum value 'QAM2'
>>> tune to: 706000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE
>>> tune to: 778000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE
>>> tune to: 2:INVERSION_AUTO:BANDWIDTH_AUTO:FEC_AUTO:FEC_AUTO:QAM_AUTO:TRANSMISSION_MODE_AUTO:GUARD_INTERVAL_AUTO:HIERARCHY_AUTO
__tune_to_transponder:1910: ERROR: Setting frontend parameters failed: 22 Invalid argument
>>> tune to: 2:INVERSION_AUTO:BANDWIDTH_AUTO:FEC_AUTO:FEC_AUTO:QAM_AUTO:TRANSMISSION_MODE_AUTO:GUARD_INTERVAL_AUTO:HIERARCHY_AUTO
__tune_to_transponder:1910: ERROR: Setting frontend parameters failed: 22 Invalid argument
>>> tune to: 770000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE
>>> tune to: 698000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE
>>> tune to: 746000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE
>>> tune to: 762000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE
WARNING: filter timeout pid 0x0011
WARNING: filter timeout pid 0x0000
WARNING: filter timeout pid 0x0010
L'analyse est commencé à partir GWT côté client via des appels RPC. Par souci de concision, voici ce code:
private void runScanQuick() {
server.checkEditAccess(user, new AsyncCallback<Boolean>() {
@Override
public void onFailure(Throwable caught) {
log.info("runScanQuick server failure");
}
@Override
public void onSuccess(Boolean result) {
if (result == false) return; // not allowed to run scan
final DialogBox dia = new DialogBox();
final Frame frame = new Frame(url_base + url_ext_scanbybroadcaster);
frame.addLoadHandler(new LoadHandler() {
@Override
public void onLoad(LoadEvent event) {
String broadcaster = scan_country.getSelectedItemText() + "-" + scan_broadcaster.getSelectedItemText();
log.info("Scan file: " + broadcaster);
Document doc = IFrameElement.as(frame.getElement()).getContentDocument();
doc.getElementById("broadcaster").appendChild(new HTML(broadcaster).getElement());
Button okay = Button.wrap(doc.getElementById("okay"));
Button cancel = Button.wrap(doc.getElementById("cancel"));
cancel.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dia.hide();
}
});
okay.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dia.hide();
runScanQuickStart();
}
});
}
});
frame.setSize("500px", "500px");
dia.add(frame);
dia.setGlassEnabled(true);
dia.setStyleName("");
dia.center();
dia.show();
}
});
}
private void runScanQuickStart() {
final DialogBox dia = new DialogBox();
final Frame frame = new Frame(url_base + url_ext_scanbroadcasterprogress);
frame.addLoadHandler(new LoadHandler() {
@Override
public void onLoad(LoadEvent event) {
Document doc = IFrameElement.as(frame.getElement()).getContentDocument();
String broadcaster = scan_country.getSelectedItemText() + "-" + scan_broadcaster.getSelectedItemText();
doc.getElementById("title").appendChild(new HTML(broadcaster).getElement());
Button okay = Button.wrap(doc.getElementById("okay"));
final TextArea area = TextArea.wrap(doc.getElementById("textarea"));
final Timer timer = new Timer() {
@Override
public void run() {
server.pollScanResult(user, new AsyncCallback<String>() {
@Override
public void onFailure(Throwable caught) {
cancel();
}
@Override
public void onSuccess(String result) {
if (result == null) cancel();
else {
area.setText(result);
}
log.info("Polled for scan result");
}
});
}
};
okay.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
timer.cancel();
dia.hide();
}
});
server.scanByBroadcaster(user, broadcaster, new AsyncCallback<Boolean>() {
@Override
public void onFailure(Throwable caught) {
log.info("runScanQuickStart server call failed");
}
@Override
public void onSuccess(Boolean result) {
if (result == false) return;
timer.scheduleRepeating(1000);
}
});
}
});
frame.setSize("740px", "500px");
dia.add(frame);
dia.setGlassEnabled(true);
dia.setStyleName("");
dia.center();
dia.show();
}
Tout fonctionne très bien en dehors du fait que je ne sais pas comment récupérer la sortie en direct du ProcessBuilder.
Est-ce que quelqu'un sait comment saisir la sortie en direct pour que je puisse afficher des commentaires en direct sur la page Web? Je pense que peut-être que ce pourrait être soit stderr, stdout ou quelque chose.