Link to home
Start Free TrialLog in
Avatar of prain
prainFlag for United States of America

asked on

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
Avatar of sciuriware
sciuriware

readLine() should read up to a '\n'.
At least it does so with me.

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

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

;JOOP!
Avatar of CEHJ
You should bereading in a loop. That code will return at most one file name
No CEHJ, the option -ld secures that only one line will be output.

;JOOP!
Sorry - ignore that
Avatar of prain

ASKER

Nop. It does not work. Creates more exceptions!.
No worries, UNIX is .............. weird nowadays.

;JOOP!
What exceptions?

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

;JOOP!
Avatar of prain

ASKER

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.
I'll check on my machine (I did such before).

;JOOP!
Try

String command[] = { "ls", "-ld", "'" + filePath + "'"};
Process p = r.exec(command);
Of course that's an error; you send a command by the name "ls -ld ..." in stead of ls, then, -ld, then filename.

;JOOP!
Avatar of prain

ASKER

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
Wrong:         Process p = r.exec("ls -ld \""  + filePath +"\"");

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

;JOOP!
>>I am getting all files null.

Did you try the command i posted?
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!
Avatar of prain

ASKER

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;
 }
prain, can you test my source?

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

;JOOP!
>>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?
Avatar of prain

ASKER

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
SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of prain

ASKER

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
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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!
And that's consistent with what you found.

;JOOP!
Avatar of prain

ASKER

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)
Does it work or not?
Avatar of prain

ASKER

sh -c ls -ld "/aaa/bbb/ccc/ddd/Test 1234"
good1        bad one      Test 1234     hello.dat
Avatar of prain

ASKER

Why is it displaying all even if I query one.
Avatar of prain

ASKER

And also it is not displying the details.
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
Try

sh -c "ls -ld '/aaa/bbb/ccc/ddd/Test 1234'"
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!
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 ? ;-)
Avatar of prain

ASKER

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

Does that work prain? Don't give up!

;JOOP!
I mean my code of course ...................

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

;JOOP!
Avatar of prain

ASKER

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.


Well the last I gave works for me as you wanted.
Does it work for you?

;JOOP!
Avatar of prain

ASKER

I think I have answred to what happened to your last suggestion.

It is not finding the file
Error....
No such file or directory
Then why does it work for me?
Did you try my code literally?
;JOOP!
I created that directory "/tmp/D I R" for my tests.
Can you do the same?

;JOOP!
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!
Is there are particular reason why you seem to be ignoring my comments prain?
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!
Avatar of prain

ASKER

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.
Avatar of prain

ASKER

CEHJ
in your commnd
java RunAsync ls -ld src

What is RunAsync ?

Prain
Avatar of prain

ASKER

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.
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!
Avatar of prain

ASKER

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.
>>What is RunAsync ?

The class i posted a while back
Avatar of prain

ASKER

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
Avatar of prain

ASKER

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.
Well it's important to consume the input and error streams on separate threads as blocking can prevent it running properly
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);
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.
>> P.S.: Webstorm, that was tried before; see a few yards higher
not without " and '
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)

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!
Avatar of prain

ASKER

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
OK - glad you're happy
Please spend some points on Webstorm: his solution is faster (1 less process spawn).

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

;JOOP!
>>1 less process spawn

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

;JOOP!
Mine didn't invoke sh ;-)
Yes, confused again. Sorry.
;JOOP!