• Post Reply Bookmark Topic Watch Topic
  • New Topic

How do I know the input stream is ready? PDF print issue.

 
Sean Li
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let me try to explain the situlation clear:

I'm trying to print a PDF file, before sending it to printer, I need to use GhostScript convert it to postscript so that most printers can recogonize it.

I have cygwin installed, then in my java code, I have:



The result is a disaster, hundreds of pages are printed. I guess it's because ghostscript convertion is too slow. If the convertion is not finished, and print is already started, hundreds of rubbish are printed.

I don't know whether my guess is right. If not, please correct me; if yes, please tell me how to determine whether the stream is ready, so that I can use it to print.

Or, could someone tell me a better way of printing PDF?
 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You should wait until the Process p is finished; p.waitFor() let's you do that.
 
Sean Li
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried p.waitFor(). But it seems waiting there forever.

Did I do something wrong?
 
Ulf Dittmer
Rancher
Posts: 42970
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's hard to tell; is your process actually exiting?

You could try separating the call into the various parts of it, and call each one in succession upon successful completion of the previous one (and not running them in a separate shell).
 
Sean Li
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks for you reply. I think I cannot rely too much on the waitfor() method, because I know it's still a bug in Java when runing in some operating system like windows 2000.

Could you tell me whether there're other ways to walk around?
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24213
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The processes won't exit until you read the output; otherwise, the partial output fills up the buffer allocated for it, and the process pauses until you empty the buffer.

Anyway, one thing you can do is to read the output and poll Process.exitValue(). I wish this method didn't throw an exception to indicate "not exited yet", but that's what you've got to work with. In any case, something like



Depending on your paranoia level, you can put a max-loop-counter into this loop, or run it in a separate thread, time it, and kill it if it runs too long.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[EFH]: The processes won't exit until you read the output

It's also possible that the process is waiting for you to read the error output - the stuff you get from getErrorStream(). I recommend reading both standard out and error out in separate threads. A process can block on either one, and you may have no way of knowing which one it's blocking on. If you try to read the wrong one first (without using separate threads) then your program may just hang indefinitely. No fun.

Check out this article for more info on using exec().
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hmm, this looks suspicious. The available() method is a horrible, evil method that never should have been included in the API, IMO. Well perhaps that's a bit of an exaggeration, but it's very rare that the thing is actually useful, and it has a good chance of misleading unwary coders, as it has above.

The problem is that if available() returns false, that doesn't necessarily mean that the stream has finished. It just means that no further data is available from the stream right now. It's entirely possible that more will be available shortly, and you should wait until it's available. For example if you're reading a file, it may take a few milliseconds for the drive head to reach the proper position to read the data. As a result, the available() method may return false when you first poll it.

So, what to do? Don't use available. Period. (Except maybe for some rare cases too esoteric to get into here.) Just use the fact that the read() method by default will wait until either more data is available, or the stream closes, and will return -1 in the latter case:

Or for greater efficiency, use a buffer to read bytes in bulk:

Of course in this particular example you could just modify your shell script to read from the file directly, rather than copy the bytes to the process input stream.
[ July 05, 2005: Message edited by: Jim Yingst ]
 
Sean Li
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:

So, what to do? Don't use available. Period. (Except maybe for some rare cases too esoteric to get into here.) Just use the fact that the read() method by default will wait until either more data is available, or the stream closes, and will return -1 in the latter case:

Or for greater efficiency, use a buffer to read bytes in bulk:

Of course in this particular example you could just modify your shell script to read from the file directly, rather than copy the bytes to the process input stream.

[ July 05, 2005: Message edited by: Jim Yingst ][/QB]


Thank you, buddy. That resolves all the problems. I don't have to know whether the process is finished or not. Just read the output until I got a -1.

The only thing is the stream I'm reading is the normal output stream. I didn't read the error output, which works for this case. My question is will it have different stuff from error steam? And how do I know which one should I read?

Thanks for the article as well. It really helps me understanding the exec() pitfalls.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Sean]: The only thing is the stream I'm reading is the normal output stream. I didn't read the error output, which works for this case. My question is will it have different stuff from error steam? And how do I know which one should I read?

Well generally, the error stream is only relevant if there are errors. If there are no errors, then you don't really need to read it, which makes life simpler. Except that, just because there are no errors now doesn't mean that there will never be any errors. Some day you may be porting your application to a new platform where your shell scripts don't work the same way they did - and if you're not reading the error stream, it can be extremely difficult to figure out why it's not working. In general I think it's easier and safer to always read the error stream and make sure there's a nice clear log entry if anything ever gets written to the error stream. If you're lucky, you'll never need this. If you're not - well, you may wish you'd read and logged the error stream in the first place, because it's very easy to overlook this sort of thing later, and it can take you awhile to track down the problem.
[ July 06, 2005: Message edited by: Jim Yingst ]
 
Sean Li
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
fully got it. thank you very much!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!