?
Solved

Process class problem

Posted on 2006-04-06
70
Medium Priority
?
272 Views
Last Modified: 2013-12-29
I have a method which is used to get the file information such as ower, create date etc.... For that I am using the Runtime class.

Here is the code...

private String getDetailsString(String filePath)
  {  
   String details = null;

   try {
         Runtime r = Runtime.getRuntime();
 
         Process p = r.exec("ls -ld " + filePath);
 
         InputStream is = p.getInputStream();
 
         BufferedReader br = new BufferedReader(new InputStreamReader(is));
       
         details = br.readLine();
   
       } catch (Exception ex) {
         ex.printStackTrace();
       }
  return details;
}


I am working on a UNIX platform. I have tons of files with their names have blanks (like "hello world.dat")
When a file name has a blank, the line details = br.readLine() sends me a null.

That causes an exception!!!!!!.

I can NO WAY change the file names to be without blanks. That's out of the question.

Can any one throw come light into this to solve it?

Thanks
prain
0
Comment
Question by:prain
  • 32
  • 20
  • 15
  • +1
70 Comments
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393865
readLine() should read up to a '\n'.
At least it does so with me.

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393878
The problem is in your 'ld' command line.
You should surround the filename with quotes.
Test for yourself when typing the same command from the shell prompt.

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393886
        Process p = r.exec("ls -ld " + filePath);
->

         Process p = r.exec("ls -ld \"" + filePath + "\"");

;JOOP!
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 86

Expert Comment

by:CEHJ
ID: 16393893
You should bereading in a loop. That code will return at most one file name
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393906
No CEHJ, the option -ld secures that only one line will be output.

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16393910
Sorry - ignore that
0
 

Author Comment

by:prain
ID: 16393919
Nop. It does not work. Creates more exceptions!.
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393920
No worries, UNIX is .............. weird nowadays.

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393929
What exceptions?

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393938
By the way, you should close the input stream and do a .waitFor() on the process.

;JOOP!
0
 

Author Comment

by:prain
ID: 16393954
After I receive the   details = br.readLine();
the details string is sent into a string tokenizer. Because the details is null (even after suggested change)
I get exceptions.
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16393972
I'll check on my machine (I did such before).

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394033
Try

String command[] = { "ls", "-ld", "'" + filePath + "'"};
Process p = r.exec(command);
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394067
Of course that's an error; you send a command by the name "ls -ld ..." in stead of ls, then, -ld, then filename.

;JOOP!
0
 

Author Comment

by:prain
ID: 16394068
I am getting all files null.

Here is the code I am using now and the output

I did that change too. I am getting all files (including the good ones null)
Here is teh code and output of few good noes(no blanks) and ones with blanks


 private String getDetailsString(String filePath)
  {  
   String details = null;

   try {
         Runtime r = Runtime.getRuntime();
System.out.println("AT DL RT : " + filePath);
         Process p = r.exec("ls -ld \""  + filePath +"\"");
System.out.println("AT DL RT : Passed - 1");
         InputStream is = p.getInputStream();
System.out.println("AT DL RT : Passed - 2");
         BufferedReader br = new BufferedReader(new InputStreamReader(is));
System.out.println("AT DL RT : Passed - 3");

       
         details = br.readLine();
System.out.println("AT DL RT Details : " + details )   ;  
         is.close();

         p.waitFor();  
       } catch (Exception ex) {
         ex.printStackTrace();
       }
  return details;
 }




....Here is the output of a file with blanks
AT DL RT : /aaa/bbb/ccc/ddd/eee/xxxxx yyyyy
AT DL RT : Passed - 1
AT DL RT : Passed - 2
AT DL RT : Passed - 3
AT DL RT Details : null
AT DL : null

Here is a file without a blank
AT DL RT : /aaa/bbb/ccc/ddd/eee/pqrst.ascii
AT DL RT : Passed - 1
AT DL RT : Passed - 2
AT DL RT : Passed - 3
AT DL RT Details : null
AT DL : null


Notice the null in  AT DL RT Details : null


prain
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394092
Wrong:         Process p = r.exec("ls -ld \""  + filePath +"\"");

must be:          Process p = r.exec(new String[]{"ls", "-ld",  "\""  + filePath +"\"");

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394124
>>I am getting all files null.

Did you try the command i posted?
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394134
Very funny CEHJ, I tested this:

         String filePath = "/tmp";
         String details = null;

          try
          {
             Runtime r = Runtime.getRuntime();
             
             Process p = r.exec("ls -ld " + filePath);
     
             InputStream is = p.getInputStream();
     
             BufferedReader br = new BufferedReader(new InputStreamReader(is));
           
             details = br.readLine();
             is.close();
             p.waitFor();
     
          }
          catch (Exception ex)
          {
             ex.printStackTrace();
          }
          System.out.println(details);
   
it gives me:

drwxrwxrwt   24 root     root         1008 2006-04-06 19:45 /tmp

So your remark does not count on LINUX.

;JOOP!
0
 

Author Comment

by:prain
ID: 16394146
Still the same. All files (ones with or without bnaks in names) comes out to be null

Here is what I have now.

 private String getDetailsString(String filePath)
  {  
   String details = null;

   try {
         Runtime r = Runtime.getRuntime();
System.out.println("AT DL RT : " + filePath);
Process p = r.exec(new String[]{"ls", "-ld",  "\""  + filePath +"\""});
//         Process p = r.exec("ls -ld \""  + filePath +"\"");
System.out.println("AT DL RT : Passed - 1");
         InputStream is = p.getInputStream();
System.out.println("AT DL RT : Passed - 2");
         BufferedReader br = new BufferedReader(new InputStreamReader(is));
System.out.println("AT DL RT : Passed - 3");

       
         details = br.readLine();
System.out.println("AT DL RT Details : " + details )   ;  
         is.close();

         p.waitFor();  
       } catch (Exception ex) {
         ex.printStackTrace();
       }
  return details;
 }
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394149
prain, can you test my source?

And the correction as suggested later is platform independent between unixes and linuxes (and mac os).

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394158
>>it gives me:

I'm not sure what your point is - i know a String isn't wrong. String[] is usually better behaved though, so i prefer it

prain - can you please post the output when you execute at the command line directly?
0
 

Author Comment

by:prain
ID: 16394239
itsme> ls -ld "Test 1234"
-rw-rw-r--   1  user   owner      102 Mar  9 13:52 Test 1234


This is what I did on the command line  (user and owner are fake ones, I cannot post them here)

But it works on teh command line.

prain
0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 180 total points
ID: 16394270
Try it with the class below, using the String[] i posted before

RunAsync.main(command);

//===================================================

import java.io.*;

/**
 *  Description of the Class
 *
 * @author     Charles
 * @created    23 February 2004
 */
public class RunAsync {

      /**
       *  Description of the Method
       *
       * @param  args  Description of the Parameter
       */
      public static void main(String args[]) {

            try {

                  if (args.length < 1) {
                        System.out.println("Usage: java RunAsync <command string>");
                        System.exit(-1);
                  }
                  Process pro = null;
                  if (args.length > 1) {
                        pro = Runtime.getRuntime().exec(args);
                  }
                  else {
                        pro = Runtime.getRuntime().exec(args[0]);
                  }
                  InputStream error = pro.getErrorStream();
                  InputStream output = pro.getInputStream();
                  Thread err = new Thread(new OutErrReader(error));
                  Thread out = new Thread(new OutErrReader(output));
                  out.start();
                  err.start();
                  pro.waitFor();
            }
            catch (java.io.IOException e) {
                  e.printStackTrace();
            }
            catch (java.lang.InterruptedException e) {
                  e.printStackTrace();
            }

      }


      /**
       *  Description of the Class
       *
       * @author     Administrator
       * @created    23 February 2004
       */
      static class OutErrReader implements Runnable {
            InputStream is;


            /**
             *Constructor for the OutErrReader object
             *
             * @param  is  Description of the Parameter
             */
            public OutErrReader(InputStream is) {
                  this.is = is;
            }


            /**
             *  Main processing method for the OutErrReader object
             */
            public void run() {
                  try {
                        BufferedReader in = new BufferedReader(new InputStreamReader(is));
                        String temp = null;
                        while ((temp = in.readLine()) != null) {
                              System.out.println(temp);
                        }
                        is.close();
                  }
                  catch (Exception e) {
                        e.printStackTrace();
                  }
            }
      }
}

0
 

Author Comment

by:prain
ID: 16394303
Here is what I found.

If I give the absolute path (which is what I want) it does not work on the command line too)

ls -ld "/aaa/bbb/ccc/ddd/Test 1234"

/aaa/bbb/ccc/ddd/Test 1234: No such file or directory
0
 
LVL 24

Accepted Solution

by:
sciuriware earned 320 total points
ID: 16394317
I finally got this working:

         String filePath = "/tmp/D A T E";
         String details = null;

          try
          {
             Runtime r = Runtime.getRuntime();
             
             Process p = r.exec(new String[]{"sh", "-c", "ls -ld \"" + filePath + "\""});
     
             InputStream is = p.getInputStream();
     
             BufferedReader br = new BufferedReader(new InputStreamReader(is));
           
             details = br.readLine();
             is.close();
             p.waitFor();
     
          }
          catch (Exception ex)
          {
             ex.printStackTrace();
          }
          System.out.println(details);


;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394333
This was very tricky prain! The sh-command solves your problem.

ls is too stupid to understand "" on the command line.
When you write "" on the prompt the shell interpretes it.

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394349
And that's consistent with what you found.

;JOOP!
0
 

Author Comment

by:prain
ID: 16394390
That shows all files, including the the ones with or without blanks, even if I type the absolute path (within quotes" of a single file)
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394399
Does it work or not?
0
 

Author Comment

by:prain
ID: 16394404
sh -c ls -ld "/aaa/bbb/ccc/ddd/Test 1234"
good1        bad one      Test 1234     hello.dat
0
 

Author Comment

by:prain
ID: 16394412
Why is it displaying all even if I query one.
0
 

Author Comment

by:prain
ID: 16394425
And also it is not displying the details.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394460
OK so i'm on Windows, but it's a bash shell:


Charles@GOOSETHINK /cygdrive/c/DOCUME~1/Charles/MYDOCU~1/java/dumpit
$ java RunAsync ls -ld src
drwxrwxrwx+ 4 Charles None 0 Apr  1  2005 src
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394484
Try

sh -c "ls -ld '/aaa/bbb/ccc/ddd/Test 1234'"
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394527
I now tested (in ECLIPSE):

         String filePath = "/tmp/D I R";
         String details = null;

          try
          {
             Runtime r = Runtime.getRuntime();
             
             Process p = r.exec(new String[]{"sh", "-c", "ls -ld \"" + filePath + "\""});
     
             InputStream is = p.getInputStream();
     
             BufferedReader br = new BufferedReader(new InputStreamReader(is));
           
             details = br.readLine();
             is.close();
             p.waitFor();
     
          }
          catch (Exception ex)
          {
             ex.printStackTrace();
          }
          System.out.println(details);
 
// It gives me:

drwxrwxr-x    3 joop     lanting        72 2006-04-06 20:10 /tmp/D I R

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394537
Note too the following

$ java RunAsync ls -ld 'a/Copy (2) of _a'
drwxrwxrwx+ 4 Charles None 0 Dec 19 17:32 a/Copy (2) of _a

Are you actually TRYING my code prain ? ;-)
0
 

Author Comment

by:prain
ID: 16394542
It is not finding the file
Error....
No such file or directory

0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394544
Does that work prain? Don't give up!

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394564
I mean my code of course ...................

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394572
By the way, I'm on SuSE LINUX 9.0, JAVA 1.5.0_06, ECLIPSE 3.2M6

;JOOP!
0
 

Author Comment

by:prain
ID: 16394598
I am not giving up. I need to get this damn thing straightened ASAP. Out customers have straightened their whiskers and about to jump on us...... :-) with red apple faces.


0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394609
Well the last I gave works for me as you wanted.
Does it work for you?

;JOOP!
0
 

Author Comment

by:prain
ID: 16394677
I think I have answred to what happened to your last suggestion.

It is not finding the file
Error....
No such file or directory
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394683
Then why does it work for me?
Did you try my code literally?
;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394694
I created that directory "/tmp/D I R" for my tests.
Can you do the same?

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394730
I checked again, my code lists as I said only the directory, not the contents:

drwxrwxr-x    3 joop     lanting        72 2006-04-06 20:10 /tmp/D I R

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16394736
Is there are particular reason why you seem to be ignoring my comments prain?
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16394826
Well, I'm not going to sit here all night in vain.
I think I finally solved the case although CEHJ did his part.

Good night.

;JOOP!
0
 

Author Comment

by:prain
ID: 16394829
No of course not. Sorry if I missed it in this long thread. I am doing two or three things here at the same time.
I will respond to you soon. There is a customer here. Give me few minutes.
0
 

Author Comment

by:prain
ID: 16394988
CEHJ
in your commnd
java RunAsync ls -ld src

What is RunAsync ?

Prain
0
 

Author Comment

by:prain
ID: 16395006
sciuriware

Sure it works upto the directory level. But the moment I add a file name, it gives me the famous

"no such file or directory"

error.
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16395203
I couldn't sleep.

I created a directory INSIDE and a file q in /tmp/D I R
I modified into:           String filePath = "/tmp/D I R/INSIDE";
and                        String filePath = "/tmp/D I R/q";
resp.

I got:    drwxrwxr-x    2 joop     lanting        48 2006-04-06 20:10 /tmp/D I R/INSIDE
and:      -rw-rw-r--    1 joop     lanting     44488 2006-02-28 14:48 /tmp/D I R/q

So, I think you should re-check your code.

Going to sleep again.

;JOOP!
0
 

Author Comment

by:prain
ID: 16395241
Wait Wait. Just a second.

Create a file inside INSIDE. Name it with a blank character such as "hello world.dat"

and then String filePath = "/tmp/D I R/INSIDE/hello world.dat";

Try it and tell me what you get.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16395328
>>What is RunAsync ?

The class i posted a while back
0
 

Author Comment

by:prain
ID: 16395503
CEHJ,

Well that seems to be working. Here is what I did

mycomp> java RunAsync ls -ld "a a.lst"
-rw-rw-r--   1 owner group    83801 Apr  6 14:57 a a.lst

I am going to work on this and extarct the code into a funciton, and will get back with you.
Some relief at last.

-prain
0
 

Author Comment

by:prain
ID: 16395523
One thought is that why we need to write such a lot of code to get this thing correct?.
I am not trying to fault anything against with what CEHJ did. Not just thinking.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16395544
Well it's important to consume the input and error streams on separate threads as blocking can prevent it running properly
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 16398882
Try this version (modification of CEHJ's suggestion) :

String command[] = { "ls", "-ld", filePath};   //   <-- no " or ' around path (done by Java/OS)
Process p = r.exec(command);
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16399280
I woke up.

I presently tried (without changing the code)          String filePath = "/tmp/D I R/INSIDE/x y z";

And it produced:

-rw-rw-r--    1 joop     lanting        30 2006-04-07 12:57 /tmp/D I R/INSIDE/x y z

So, what's the difference between your situation and mine?????????

;JOOP!

P.S.: Webstorm, that was tried before; see a few yards higher.
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 16399398
>> P.S.: Webstorm, that was tried before; see a few yards higher
not without " and '
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 16399418
sciuriware, here is the list of the solution posted here, before my comment:
    String command[] = { "ls", "-ld", "'" + filePath + "'"};
    Process p = r.exec(new String[]{"ls", "-ld",  "\""  + filePath +"\"");
    r.exec(new String[]{"ls", "-ld",  "\""  + filePath +"\""});
    r.exec(new String[]{"sh", "-c", "ls -ld \"" + filePath + "\""});
    r.exec(new String[]{"sh", "-c", "ls -ld \"" + filePath + "\""});

And my suggestion is:
    String command[] = { "ls", "-ld", filePath};   //   <-- no " or ' around path (done by Java/OS)

0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16399492
Yes, I tested it. It works and is even faster as mine or CEHJ's.
I still wonder what's wrong with that @#$%^& system of prain.
I'm afraid that he (she?) didn't tell us all about the situation.
;JOOP!
0
 

Author Comment

by:prain
ID: 16399886
Ok, I am back Friday early morning.
Gosh this thread has gone very far.

Ok. sciuriware I am sorry. It works. But it doe not work for the siggle quote. It works for the double quote (i am talking about the quotes surounding the file path. I do not have an explnation for that. But I am happy that at leat it works with something.

So I decided to go with that as I need to gert this error fixed before I received "firing orders" .

So what am I to say.... THANK YOU  sciuriware VERY MUCH.

CEHJ: I really appreciate your effort too. Your code works as well. But I would rather go with the  sciuriware 's solution. Otherwise I have to go through a tough process of configuration mgmt/Peer Review process to add new code.

Points.... Hmmm. Both you guys worked really hard on this. Therefore I will split the points, with sciu getting a bit more because he went through a SEELPLESS NIGHT. Actuall even I could not sleep well.

Thanks Guys.

prain
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16399917
OK - glad you're happy
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16399935
Please spend some points on Webstorm: his solution is faster (1 less process spawn).

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16399951
Anyway, others may learn from this thread.
Thanks and goodbye.

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16399958
>>1 less process spawn

How so? (i must have missed something)
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16399976
Spawning sh to spawn ls  in stead of spawning ls directly.

;JOOP!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16399981
Mine didn't invoke sh ;-)
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 16400477
Yes, confused again. Sorry.
;JOOP!
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

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

Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month16 days, 13 hours left to enroll

864 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