[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Lynx, Java, & Runtime.getRuntime().exec()

Posted on 2004-10-06
6
Medium Priority
?
1,920 Views
Last Modified: 2008-02-01
LYnx is a text based browser.  It can convert .html files to its rough equivalent in text.

I am trying to use a simple java program to call lynx.bat or lynx.exe .

Lynx.bat is located in C:\Lynx\lynx.bat

I want to use the "-dump" parameter.

Then I must put the name of the file "mydoc.htm"

Then the name of the new file "mydoctxt.txt"

So in completion it would look like this "lynx.bat -dump mydoc.htm > mydoctxt.txt"

This works completely fine from the command line, but when I try to wrap it in a simple java program, it fails.

Here is what I have so far...

package javaapplication2;
import      java.io.*;
class Main{
   
    public static void main(String argv[]) {
       
        try {
            String ls_str;
           
            //Process ls_proc = Runtime.getRuntime().exec("cmd.exe /E :1900 C:\\lynx\\lynx.exe -dump C:\\test.htm > C:\\test6.txt");
            Process ls_proc = Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\test5.txt");

           
            DataInputStream ls_in = new DataInputStream(
            ls_proc.getInputStream());
           
           
            try {
                while ((ls_str = ls_in.readLine()) != null) {
                    System.out.println(ls_str);

                }
            } catch (IOException e) {
                System.out.println("1st catch block");
                System.exit(0);


            }
        } catch (IOException e1) {
            System.err.println(e1);
            System.out.println("2nd catch block");
            System.exit(1);
        }
       
        System.exit(0);
       
       
    }
   
   
}

When I run that a blank text file called test5.txt is created.  It is 0kb in length.  If I run it straight from the command line in windows XP though, test5.txt is created successfully.  If I uncomment out Process ls_proc = Runtime.getRuntime().exec("cmd.exe /E :1900 C:\\lynx\\lynx.exe -dump C:\\test.htm > C:\\test6.txt"); and comment out the other line, the program lags and nothing happens.

I know I have to be missing something simple here, because I whipped up the equivalent prog in VB, in like 3 minutes.
0
Comment
Question by:bullyellis
6 Comments
 
LVL 4

Expert Comment

by:gdrnec
ID: 12240962
I had this problem once and I think that I solved by using Runtime.exec(String[] cmdarray) method instead of all one string.

so String[] cmdarray = {"C:\\lynx\\lynx.bat","-dump","C:\\test.htm",">","C:\\test5.txt"};
Runtime.getRuntime().exec(cmdarray);

I think I remeber this solving it. Hope I'm right.

Geoff
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12241055
Sure it isn't a matter of (back) slashes.

Did you try these already?

            Process ls_proc = Runtime.getRuntime().exec("cmd.exe /E :1900 C:/lynx/lynx.exe -dump C:/test.htm > C:/test6.txt");
or
            Process ls_proc = Runtime.getRuntime().exec("C:/lynx/lynx.bat -dump C:/test.htm > C:/test5.txt");
0
 
LVL 13

Accepted Solution

by:
Webstorm earned 1000 total points
ID: 12242159
Hi bullyellis,

You cannot redirect the output with ">" unless you use cmd.exe.
You have to redirect the outputstream from the Process class to a FileOutputStream like that :

String[] cmdarray = {"cmd.exe","/E:1900","/C","C:\\lynx\\lynx.bat","-dump","C:\\test.htm"};
//String[] cmdarray = {"C:\\lynx\\lynx.exe,"-dump","C:\\test.htm"};

// cmd.exe to invoke the batch file is necessary, but not for the .exe file

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\test5.txt"),
          System.in,false,
          new FileOutputStream("C:\\test5.txt"),true, // stdout redirection
          System.err,false);


// And the RunProcess class is :


public class RunProcess
{
    private Process p=null;
    private static final int BUFFER_SIZE=8192;
    private Thread th_in=null,th_out=null,th_err=null;
    private int ret_code=-1;

    public RunProcess(
        final Process p,
        final InputStream p_in,   final boolean in_close,
        final OutputStream p_out, final boolean out_close,
        final OutputStream p_err, final boolean err_close)
    {
        this.p=p;

        // Process. OUT
        (th_out=new Thread(){
            byte b[]=new byte[BUFFER_SIZE];
            InputStream inp=p.getInputStream();
            public void run()
            {
                try{
                    for(;;)
                    {
                        int sz=inp.read(b);
                        if (p_out!=null) p_out.write(b,0,sz);
                    }
                }catch(Exception e){}
            }
        }).start();

        // Process. ERR
        (th_err=new Thread(){
            byte b[]=new byte[BUFFER_SIZE];
            InputStream inp=p.getErrorStream();
            public void run()
            {
                try{
                    for(;;)
                    {
                        int sz=inp.read(b);
                        if (p_err!=null) p_err.write(b,0,sz);
                    }
                }catch(Exception e){}
            }
        }).start();

        if (p_in!=null)
        // Process. IN
        (th_in=new Thread(){
            byte b[]=new byte[BUFFER_SIZE];
            OutputStream outp=p.getOutputStream();
            public void run()
            {
                try{
                    for(;;)
                    {
                        int sz=p_in.read(b);
                        outp.write(b,0,sz);
                    }
                }catch(Exception e){}
            }
        }).start();

        (new Thread(){
            public void run()
            {
                try{
                    ret_code=p.waitFor();
                }catch(Exception ex){}
                if (th_in!=null) th_in.interrupt();
                try{if (in_close&&(p_in!=null)) p_in.close();}catch(Exception ex){}
                try{if (out_close&&(p_out!=null)) p_out.close();}catch(Exception ex){}
                try{if (err_close&&(p_err!=null)) p_err.close();}catch(Exception ex){}
                if (th_out!=null) th_out.interrupt();
                if (th_err!=null) th_err.interrupt();
            }
        }).start();
    }

    public int getReturnCode()
    {
        return ret_code;
    }

    public int waitFor() throws Exception
    {
        return p.waitFor();
    }

    public void destroy()
    {
        p.destroy();
    }
}
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
LVL 92

Expert Comment

by:objects
ID: 12244080
Here an examples of handing the output from a Process that you should be able to easily adapt to your requirements.

http://www.objects.com.au/java/examples/util/ConsoleExec.do
0
 

Author Comment

by:bullyellis
ID: 12244728
WebStorm,

Your code works kind of.

The problem I ran into was

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\test5.txt"),
          System.in,false,
          new FileOutputStream("C:\\test5.txt"),true, // stdout redirection
          System.err,false);

The 2 instances of "test5.txt" can not be named the same thing.

I get an error that "The process cannot access the file because it is being used by another process."  And again I get the empty text file.

However if I change the code to

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\testa.txt"),
          System.in,false,
          new FileOutputStream("C:\\testb.txt"),true, // stdout redirection
          System.err,false);

Then I get both testa and testb.  testa.txt works correctly and is what I want.  testb.txt however is another empty text file.

Could you explain this ?

0
 
LVL 13

Expert Comment

by:Webstorm
ID: 12257048
bullyellis, thanks for the points

When you specify a redirection with '>', cmd.exe will redirect output to this file. So, nothing will be written to the process's stdout stream, and you get an empty file.
If you specify a FileOutputStream you don't have to specify another redirection in the command line and it's only usable with cmd.exe :

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm"),
          System.in,false,
          new FileOutputStream("C:\\testa.txt"),true, // stdout redirection
          System.err,false);

Or

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\testa.txt"),
          System.in,false,
          System.out,false,
          System.err,false);

0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
Suggested Courses
Course of the Month9 days, 7 hours left to enroll

591 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question