Transferring data through an external application in Windows using Java

I have a Java application with an InputStream that copies data to an OutputStream. I want to compress data from an InputStream using FreeArc before writing it to an OutputStream.

The problem is the lack of a Java API for FreeArc. So I need to somehow pass it through the exe command line. That is, I need to trick FreeArc into reading and writing two files when it really reads my InputStream and writes to my OutputStream. On Unix, it's pretty simple, but I have to make this work on Windows.

How do you suggest me to do this? Is there a way to access Windows named pipes in Java, or can I do this through sockets? Something other? This will be done ~ 1 / s, so the overhead cannot be too high.

+3
source share
3 answers

If freearc can accept input from standard input and send output to the standard version, then ProcessBuilderyou can use it to invoke the command and the returned instance Processwill produce the standard input and output of an external process.

+2
source

Here is an example taken from code designed to convert EPS to PDF through GhostScript:

  // Start the script as OS process.
  ProcessBuilder pb = new ProcessBuilder(gsExecutable, pdfFileName, epsFile.getName());
  pb.directory(gsDir);
  pb.redirectErrorStream(true);
  Process proc = pb.start();
  final InputStream stdErrInStream = proc.getErrorStream();
  final InputStream stdOutInStream = proc.getInputStream();

  // Read the STDERR-Stream.
  String className = EpsToJpegConverter.class.getName();
  final ByteArrayOutputStream stdErrOutStream = new ByteArrayOutputStream();
  new Thread(new Runnable() {
    @Override
    public void run() {
      try {
        byte[] buf = new byte[16];
        int len = -1;
        while ((len = stdErrInStream.read(buf)) != -1) {
          stdErrOutStream.write(buf, 0, len);
        }
        stdErrFertig = true;
      } catch (IOException e) {
        log.error(e.getLocalizedMessage(), e);
      }
    }
  }, className + " Script STDERR Reader").start();

  // Read the STDOUT-Stream.
  final ByteArrayOutputStream stdOutOutStream = new ByteArrayOutputStream();
  new Thread(new Runnable() {
    @Override
    public void run() {
      try {
        byte[] buf = new byte[4096];
        int len = -1;
        while ((len = stdOutInStream.read(buf)) != -1) {
          stdOutOutStream.write(buf, 0, len);
        }
        stdOutFertig = true;
      } catch (IOException e) {
        log.error(e.getLocalizedMessage(), e);
      }
    }
  }, className + " Script STDOUT Reader").start();

  // Wait for the process to finish.
  int waitFor = proc.waitFor();
  if (waitFor != 0) {
    // If an error occured, the return code is != 0.
    // In this case wait for the reading threads to finish.
    while (!stdOutFertig || !stdErrFertig) {
      Thread.sleep(100);
    }
    throw new EpsConverterException("Das Konvertierungsscript " + gsExecutable
        + " wurde nicht erfolgreich ausgeführt.\nStandardausgabe:\n" + new String(stdOutOutStream.toByteArray())
        + "\nFehlerausgabe:\n" + new String(stdErrOutStream.toByteArray()));
  }

NTN.

Edit: Perhaps the code that reads the inverse bytes of the image is also interesting:

  // If everything worked out ok, read the PDF.
  pdfFile = new File(gsDir, pdfFileName);
  FileInputStream pdfInStream = new FileInputStream(pdfFile);
  int len = -1;
  byte[] buf = new byte[4096];
  ByteArrayOutputStream pdfBAOS = new ByteArrayOutputStream(65535);
  while ((len = pdfInStream.read(buf)) != -1) {
    pdfBAOS.write(buf, 0, len);
  }
  pdfInStream.close();

  byte[] res = pdfBAOS.toByteArray();
  return res;
+1

ZIP, J2SE (. java.util.zip docs), FreeArc (, 1 10 ), ZIP . FreeArc, :

  • , ProcessBuilder, . NIO- , IO ( ). , Java, .
  • JNI + API FreeArc ( , / ).
  • Use JNI + your own Windows API to create a named pipe that will connect to your application and FreeArc, then you can work with it like a regular file.

Finally, you can reduce the file io if the input or output is a file. For instance. if you are reading from a file, just run FreeArc directly against it, and then send the compressed file for output. Also, this may not be worth all the problems if: a) the data size is relatively small - perhaps up to several megabytes; or b) compression does not sharply reduce it

0
source

Source: https://habr.com/ru/post/1786749/


All Articles