• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 275
  • Last Modified:

Process class problem

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
prain
Asked:
prain
  • 32
  • 20
  • 15
  • +1
2 Solutions
 
sciuriwareCommented:
readLine() should read up to a '\n'.
At least it does so with me.

;JOOP!
0
 
sciuriwareCommented:
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
 
sciuriwareCommented:
        Process p = r.exec("ls -ld " + filePath);
->

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

;JOOP!
0
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.

 
CEHJCommented:
You should bereading in a loop. That code will return at most one file name
0
 
sciuriwareCommented:
No CEHJ, the option -ld secures that only one line will be output.

;JOOP!
0
 
CEHJCommented:
Sorry - ignore that
0
 
prainAuthor Commented:
Nop. It does not work. Creates more exceptions!.
0
 
sciuriwareCommented:
No worries, UNIX is .............. weird nowadays.

;JOOP!
0
 
sciuriwareCommented:
What exceptions?

;JOOP!
0
 
sciuriwareCommented:
By the way, you should close the input stream and do a .waitFor() on the process.

;JOOP!
0
 
prainAuthor Commented:
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
 
sciuriwareCommented:
I'll check on my machine (I did such before).

;JOOP!
0
 
CEHJCommented:
Try

String command[] = { "ls", "-ld", "'" + filePath + "'"};
Process p = r.exec(command);
0
 
sciuriwareCommented:
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
 
prainAuthor Commented:
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
 
sciuriwareCommented:
Wrong:         Process p = r.exec("ls -ld \""  + filePath +"\"");

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

;JOOP!
0
 
CEHJCommented:
>>I am getting all files null.

Did you try the command i posted?
0
 
sciuriwareCommented:
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
 
prainAuthor Commented:
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
 
sciuriwareCommented:
prain, can you test my source?

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

;JOOP!
0
 
CEHJCommented:
>>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
 
prainAuthor Commented:
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
 
CEHJCommented:
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
 
prainAuthor Commented:
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
 
sciuriwareCommented:
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
 
sciuriwareCommented:
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
 
sciuriwareCommented:
And that's consistent with what you found.

;JOOP!
0
 
prainAuthor Commented:
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
 
sciuriwareCommented:
Does it work or not?
0
 
prainAuthor Commented:
sh -c ls -ld "/aaa/bbb/ccc/ddd/Test 1234"
good1        bad one      Test 1234     hello.dat
0
 
prainAuthor Commented:
Why is it displaying all even if I query one.
0
 
prainAuthor Commented:
And also it is not displying the details.
0
 
CEHJCommented:
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
 
CEHJCommented:
Try

sh -c "ls -ld '/aaa/bbb/ccc/ddd/Test 1234'"
0
 
sciuriwareCommented:
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
 
CEHJCommented:
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
 
prainAuthor Commented:
It is not finding the file
Error....
No such file or directory

0
 
sciuriwareCommented:
Does that work prain? Don't give up!

;JOOP!
0
 
sciuriwareCommented:
I mean my code of course ...................

;JOOP!
0
 
sciuriwareCommented:
By the way, I'm on SuSE LINUX 9.0, JAVA 1.5.0_06, ECLIPSE 3.2M6

;JOOP!
0
 
prainAuthor Commented:
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
 
sciuriwareCommented:
Well the last I gave works for me as you wanted.
Does it work for you?

;JOOP!
0
 
prainAuthor Commented:
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
 
sciuriwareCommented:
Then why does it work for me?
Did you try my code literally?
;JOOP!
0
 
sciuriwareCommented:
I created that directory "/tmp/D I R" for my tests.
Can you do the same?

;JOOP!
0
 
sciuriwareCommented:
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
 
CEHJCommented:
Is there are particular reason why you seem to be ignoring my comments prain?
0
 
sciuriwareCommented:
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
 
prainAuthor Commented:
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
 
prainAuthor Commented:
CEHJ
in your commnd
java RunAsync ls -ld src

What is RunAsync ?

Prain
0
 
prainAuthor Commented:
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
 
sciuriwareCommented:
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
 
prainAuthor Commented:
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
 
CEHJCommented:
>>What is RunAsync ?

The class i posted a while back
0
 
prainAuthor Commented:
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
 
prainAuthor Commented:
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
 
CEHJCommented:
Well it's important to consume the input and error streams on separate threads as blocking can prevent it running properly
0
 
WebstormCommented:
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
 
sciuriwareCommented:
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
 
WebstormCommented:
>> P.S.: Webstorm, that was tried before; see a few yards higher
not without " and '
0
 
WebstormCommented:
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
 
sciuriwareCommented:
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
 
prainAuthor Commented:
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
 
CEHJCommented:
OK - glad you're happy
0
 
sciuriwareCommented:
Please spend some points on Webstorm: his solution is faster (1 less process spawn).

;JOOP!
0
 
sciuriwareCommented:
Anyway, others may learn from this thread.
Thanks and goodbye.

;JOOP!
0
 
CEHJCommented:
>>1 less process spawn

How so? (i must have missed something)
0
 
sciuriwareCommented:
Spawning sh to spawn ls  in stead of spawning ls directly.

;JOOP!
0
 
CEHJCommented:
Mine didn't invoke sh ;-)
0
 
sciuriwareCommented:
Yes, confused again. Sorry.
;JOOP!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

  • 32
  • 20
  • 15
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now