0

I am trying to read the output of a process (webtorrent-cli, running on NodeJS) which was created by my application. I am using this library for process management. The API allows to pass an OutputStream which will receive the output coming from the process. I am passing an instance of ByteArrayOutputStream, reading its content as UTF-8 String every n seconds and then processing it further. Here is the simplified code:

import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.ProcessResult;

import java.io.*;
import java.util.concurrent.*;

public class General {
    private static Thread runProcess() {
        final Object LOCK = new Object();

        return new Thread(() -> {
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ProcessExecutor executor = new ProcessExecutor()
                        .command("\"node/webtorrent.cmd\"",
                                "download",
                                "\"magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel\"",
                                "--select 1")
                        .destroyOnExit()
                        .redirectOutput(baos)
                        .readOutput(true);

                Future <ProcessResult> ft = executor.start().getFuture();

                // Schedule a service to print the content of baos each second
                final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
                service.scheduleAtFixedRate(() -> {
                    synchronized (LOCK) {
                        try {
                            String str = baos.toString("UTF-8");

                            System.out.println("-----------------------------------------------------------------------");
                            System.out.println(str);
                            System.out.println("-------TRIMMED");
                            System.out.println(str.trim());
                            System.out.println("-----------------------------------------------------------------------");
                            baos.reset();
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }, 0, 1, TimeUnit.SECONDS);

                ft.get();
                // Shutdown
                service.shutdown();
            } catch (IOException | InterruptedException | ExecutionException ioe) {
                ioe.printStackTrace();
            }
        });
    }

    public static void main(String[] args) throws InterruptedException {
        Thread process = runProcess();
        process.start();
        process.join();
    }
}

Here is a snapshot of the output once the download is started:

-----------------------------------------------------------------------
Downloading: Sintel
Server running at: http://localhost:8000/5
Downloading to: D:\justtest
Speed: 167 KB/s  Downloaded: 786 KB/129 MB  Uploaded: 0 B
Running time: 7 seconds  Time remaining: 13 minutes  Peers: 6/7

S   196.221.61.235:6881       0 B        0 B/s        0 B/s       

... and 6 more

-------TRIMMED
[32mDownloading: Sintel
Server running at: http://localhost:8000/5
Downloading to: D:\justtest
Speed: 167 KB/s  Downloaded: 786 KB/129 MB  Uploaded: 0 B
Running time: 7 seconds  Time remaining: 13 minutes  Peers: 6/7

S   196.221.61.235:6881       0 B        0 B/s        0 B/s       

... and 6 more
-----------------------------------------------------------------------

Note that when the String is trimmed, there is this [32m appended in the beginning. I've no idea where is that coming from. I'm guessing that it's garbage that already existed in the ByteArrayOutputStream but how am I supposed to get rid of it? This is really giving me a hard time. I've to split the String by newlines and extract values for each column (e.g.: Downloading, Server running at etc.). If I split the string and proceed further, things get even messier. I get [32m for values of each column and this time [32m becomes different (like 23, it's random 2-4 letters which certainly contain digits and optionally other characters like [) for some values. How can clean the output?

  • Okay...so after some searching and banging my head against the wall, I think those numbers are color codes. Still though, how can I filter out all the color codes? –  May 20 '19 at 11:01
  • 1
    Look at https://stackoverflow.com/questions/14652538/remove-ascii-color-codes – Sascha May 20 '19 at 13:21
  • @Sascha Thanks! I figured out the issue but didn't find a good answer. As a workaround, I removed color and other styling from webtorrent's `cmd.js`. That too did the trick, but what you suggested is a more general solution as the developer might not have access to the source code of process he has to start within app. I used this regex to replace the colors and it worked: `str.replaceAll("\u001B\\[[;\\d]*m", "")`. –  May 20 '19 at 16:33

0 Answers0