prain
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
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
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!
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!
->
Process p = r.exec("ls -ld \"" + filePath + "\"");
;JOOP!
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!
;JOOP!
Sorry - ignore that
ASKER
Nop. It does not work. Creates more exceptions!.
No worries, UNIX is .............. weird nowadays.
;JOOP!
;JOOP!
What exceptions?
;JOOP!
;JOOP!
By the way, you should close the input stream and do a .waitFor() on the process.
;JOOP!
;JOOP!
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.
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!
;JOOP!
Try
String command[] = { "ls", "-ld", "'" + filePath + "'"};
Process p = r.exec(command);
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!
;JOOP!
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
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
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
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!
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?
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!
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!
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;
}
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!
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?
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?
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
-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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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!
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!
;JOOP!
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?
ASKER
sh -c ls -ld "/aaa/bbb/ccc/ddd/Test 1234"
good1 bad one Test 1234 hello.dat
good1 bad one Test 1234 hello.dat
ASKER
Why is it displaying all even if I query one.
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/Charl es/MYDOCU~ 1/java/dum pit
$ java RunAsync ls -ld src
drwxrwxrwx+ 4 Charles None 0 Apr 1 2005 src
Charles@GOOSETHINK /cygdrive/c/DOCUME~1/Charl
$ 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'"
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!
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 ? ;-)
$ 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 ? ;-)
ASKER
It is not finding the file
Error....
No such file or directory
Error....
No such file or directory
Does that work prain? Don't give up!
;JOOP!
;JOOP!
I mean my code of course ...................
;JOOP!
;JOOP!
By the way, I'm on SuSE LINUX 9.0, JAVA 1.5.0_06, ECLIPSE 3.2M6
;JOOP!
;JOOP!
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!
Does it work for you?
;JOOP!
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
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!
Did you try my code literally?
;JOOP!
I created that directory "/tmp/D I R" for my tests.
Can you do the same?
;JOOP!
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!
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!
I think I finally solved the case although CEHJ did his part.
Good night.
;JOOP!
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.
I will respond to you soon. There is a customer here. Give me few minutes.
ASKER
CEHJ
in your commnd
java RunAsync ls -ld src
What is RunAsync ?
Prain
in your commnd
java RunAsync ls -ld src
What is RunAsync ?
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.
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!
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!
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.
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
The class i posted a while back
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
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
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.
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);
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.
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 '
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)
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!
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!
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
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!
;JOOP!
Anyway, others may learn from this thread.
Thanks and goodbye.
;JOOP!
Thanks and goodbye.
;JOOP!
>>1 less process spawn
How so? (i must have missed something)
How so? (i must have missed something)
Spawning sh to spawn ls in stead of spawning ls directly.
;JOOP!
;JOOP!
Mine didn't invoke sh ;-)
Yes, confused again. Sorry.
;JOOP!
;JOOP!
At least it does so with me.
;JOOP!