LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-27-2012, 01:41 AM   #1
fakie_flip
Senior Member
 
Registered: Feb 2005
Location: San Antonio, Texas
Distribution: Gentoo Hardened using OpenRC not Systemd
Posts: 1,495

Rep: Reputation: 85
*Nix Pipe in Java


Greetings. I was given this example and told it does an equivalent of a pipe | in Java.

Code:
import java.io.*;
class PipeExample {
   public static void main(String[] args) {
      try { 
          Process p = Runtime.getRuntime().exec("uname -a"); 
          BufferedReader in = new BufferedReader( 
                              new InputStreamReader(p.getInputStream())); 
          String line = null; 
          while ((line = in.readLine()) != null) { 
             System.out.println(line); 
          } 
         
       } catch (IOException e) { 
          e.printStackTrace(); 
         }
    } 
}
I am attempting to write a front end text to speach reader for Linux. This is just source I wrote to test this concept of being able to pipe stdout of one command to stdin of another in Java. This is what I am trying to accomplish in Java.

espeak -g 20 -a 10 -p 50 -s 160 <text to read> | mbrola /usr/share/mbrola/us1/us1 -- | aplay

I do not know how to complete it at the the end. Can someone give me some pointers?

Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ReadIt {

  public static void main(String[] args) {
    if(args == null || args.length != 1) {
      System.err.println("Usage: java ReadIt \"text to read\"");
      System.exit(-1);
    }

    String[] espeakcmd = new String[]{"espeak", "-g 20", "-a 10", "-p 50", "-s 160", args[0]};
    String[] mbrolacmd = new String[]{"mbrola", "/usr/share/mbrola/us1/us1", "--"};
    String[] aplaycmd = new String[]{"aplay"};

    Process espeakPs = null, mbrolaPs = null, aplayPs = null;
    try {
      espeakPs = Runtime.getRuntime().exec(espeakcmd);
      mbrolaPs = Runtime.getRuntime().exec(mbrolacmd);
      aplayPs = Runtime.getRuntime().exec(aplaycmd);
    } catch (IOException ex) {
      Logger.getLogger(ReadIt.class.getName()).log(Level.SEVERE, null, ex);
    }

    BufferedReader ein, min, ain;

    ein = new BufferedReader(new InputStreamReader(espeakPs.getInputStream()));

    String line = null, str = null;
    try {
      while((line = ein.readLine()) != null) {
        str += line;
      }
    } catch (IOException ex) {
      Logger.getLogger(ReadIt.class.getName()).log(Level.SEVERE, null, ex);
    }
   
    // Need str piped to mbrola as input
   
  }
}
 
Old 03-27-2012, 10:00 PM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
You have to copy data from stdout of one process to stdin of the next, this blog post seems to have reasonable example code.
 
Old 03-28-2012, 04:41 PM   #3
Enrix
Member
 
Registered: Mar 2012
Location: Aguascalientes, mx
Distribution: Opensuse 12.1 x86-64
Posts: 34

Rep: Reputation: 1
Quote:
Originally Posted by fakie_flip View Post
Greetings. I was given this example and told it does an equivalent of a pipe | in Java.

Code:
import java.io.*;
class PipeExample { ...

Hello,

You must get the output stream for every process you run. otherwise, the output streams will fill up and the app will stop working. We have had this situation with an external load to oracle and the program just do nothing after some time of execution as the stream was filled... it's not a bad idea to put this code (from your example):
Code:
ein = new BufferedReader(new InputStreamReader(espeakPs.getInputStream()));

    String line = null, str = null;
    try {
      while((line = ein.readLine()) != null) {
        str += line;
      }
    } catch (IOException ex) {
Also, the page that ntubski has given to you is a good example. Please check if this works =D
 
Old 04-10-2012, 12:37 PM   #4
fakie_flip
Senior Member
 
Registered: Feb 2005
Location: San Antonio, Texas
Distribution: Gentoo Hardened using OpenRC not Systemd
Posts: 1,495

Original Poster
Rep: Reputation: 85
Exclamation

Hello ntubski and Enrix. Thanks for the replies. So using that Piper class from the blog, I wrote a my own Java test class using it, and it worked with piping audio. I was able to cat music.wav to lame and have it create an mp3. That was just a test, but then I realized that I needed to be able to simulate a command that has two pipes e.g. (Piper.java handles only 1 pipe)

Code:
espeak <text to read> | mbrola /usr/share/mbrola/us1/us1 -- | aplay
So how would I go about doing that? Should I create 2 instances of Piper.java?

I tried creating a modified Piper.java with a constructor that looks like

Code:
    public PiperThree(java.io.InputStream input1, java.io.OutputStream output2, java.io.InputStream input3) {
        this.input = input1;
        this.output = output2;
        this.input = input3;
    }
The number corresponds to which command. I am confused how to what needs to be done in the run() method to implement this to work. Help please.
 
Old 04-10-2012, 03:33 PM   #5
Enrix
Member
 
Registered: Mar 2012
Location: Aguascalientes, mx
Distribution: Opensuse 12.1 x86-64
Posts: 34

Rep: Reputation: 1
Hello Again,

You can have many pipes opened at the same time, but you need to have the reference to all of them at the same time:

Quote:
Originally Posted by fakie_flip View Post
Hello ntubski and Enrix. Thanks for the replies. So using that Piper class from the blog, I wrote a my own Java test class using it, and it worked with piping audio. I was able to cat music.wav to lame and have it create an mp3. That was just a test, but then I realized that I needed to be able to simulate a command that has two pipes e.g. (Piper.java handles only 1 pipe)
....
Also, you can send more than 1 argument from the command line, in this form:
java app argument1 argument2 .. argumentx

Keep in mind that the arguments are separated by a space, if you will send text, use quotes ("). this link might help you: http://docs.oracle.com/javase/tutori...dLineArgs.html

The way to manage the pipes is up to you, but i would consider have 1 Input / Output stream pair for each pipe.

btw, which run() method you're talking about? it's possible to share your code or part of it?
 
Old 04-10-2012, 09:07 PM   #6
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by fakie_flip View Post
That was just a test, but then I realized that I needed to be able to simulate a command that has two pipes e.g. (Piper.java handles only 1 pipe)
The same blog post talks about piping multiple processes, look at the code under the heading "Piping Between More Than Two Processes".
 
Old 04-18-2012, 01:20 AM   #7
fakie_flip
Senior Member
 
Registered: Feb 2005
Location: San Antonio, Texas
Distribution: Gentoo Hardened using OpenRC not Systemd
Posts: 1,495

Original Poster
Rep: Reputation: 85
I like Groovy's way of doing it. I am not sure if it's possible to put Groovy code in my Java App and have it work. I did a little research on that, and one example showed Java calling a groovy script. Since Groovy is backwards compatible with Java, can I compile the Java App with Groovy? I'll try to do it, but ant scripts are setup by Netbeans right now.

Update: Not compiling

Code:
bull•NetBeansProjects/JSpeak/src(master⚡)» javac -cp /usr/share/java/miglayout.jar:. jspeak/JSpeak.java                   [1:23:06]
bull•NetBeansProjects/JSpeak/src(master⚡)» groovyc -cp /usr/share/java/miglayout.jar:. jspeak/JSpeak.java                 [1:23:44]
/usr/bin/build-classpath: error: Could not find ../../jvm/java/lib/tools Java extension for this JVM
/usr/bin/build-classpath: error: Some specified jars were not found
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
jspeak/JSpeak.java: 63: unexpected token: espeak @ line 63, column 47.
   tRuntime().exec( new String[]{"espeak", 
                                 ^

1 error

bull•NetBeansProjects/JSpeak/src(master⚡)»

Last edited by fakie_flip; 04-18-2012 at 01:24 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
org.omg.CORBA.COMM_FAILURE: IOException: java.net.SocketException: Broken pipe (errno julu.99 Linux - Networking 0 12-21-2011 01:23 AM
Writing to a named pipe in Java the_7th_world Programming 2 11-21-2007 02:25 AM
JAVA and TOMCAT problem : Broken Pipe fellsin Linux - Software 1 01-13-2005 01:47 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:01 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration