I currently have the following sample code that I am trying to convert OutputStream to InputStream, which I got the idea from Method 2
in http://blog.ostermiller.org/convert-java-outputstream-inputstream
But my question here is, the save method could throw IOException, and I would like to catch that and re-throw that as part of this getInputStream method.
I am trying to wrap the IOException thrown by save(out) to a runtime exception, but I know that this runtime exception cannot be caught by the parent thread. So I am stuck on this, can anyone point me some directions?
public InputStream getInputStream() throws IOException {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
Thread t = new Thread(new Runnable() {
public void run () {
try {
save(out); // this save method can throw IOException
} catch (IOException e) {
throw new RuntimeException("Failed to save entries to output stream", e);
}
}
});
t.start();
return in;
}
private void save(OutputStream out) throws IOException {...}
I have read How to catch an Exception from a thread but felt my question is still different, because I want to re-throw the exception in parent thread, the question above solves the problem that catches the exception only
While all the comments that lead to uncaught exception handler and similar stuff are correct, I would like to post this answer as an alternative.
You can use an ExecutorService which will return you a Future and then you can catch ExecutionException when getting the result, something like this (typing directly here, might need some validation):
ExecutorService pool = Executors.newFixedThreadPool(1);
Future result = pool.submit(this::save);
result.get(); // will throw ExecutionException
But my question here is, the save method could throw IOException, and I would like to catch that and re-throw that as part of this getInputStream method.
You can't do that, because an exception can be raised in the background thread executing save()
long after getInputStream()
returns.
If save()
can throw an exception for some reason other than an IOException
from its PipedOutputStream
, and you want to convey some information about that failure to the thread that is reading from the PipedInputStream
, submitting a Callable
to an ExecutorService
is probably the right approach. An example of this case would be that save()
queries a database, and writes the results to a stream; if query fails, you want to log that SQLException
in the thread that is reading that stream. The reading thread could read the PipedInputStream
, and then check the Future
it received from submitting the task to the ExecutorService
to see if it completed abnormally.
But if you don't need any information from the exception thrown by save()
, and just want to throw an exception in the thread reading from the corresponding PipedInputStream
, simply let the background thread die. This will raise a "broken pipe" IOException
in the main thread when it attempts to read from its PipedInputStream
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.