How to append CharStreams? - java

When I use the object OutputSupplier, adding the first line (CharStreams.write) is executed correctly. But then calling CharStreams.write again throws an IOException.
Is this the correct behavior of the object? If so, how can you append a String to the supplier object without closing the inline stream?
...
final Process process = Runtime.getRuntime().exec("su");
OutputSupplier<OutputStreamWriter> writerSupplier = CharStreams.newWriterSupplier(new OutputSupplier<OutputStream>() {
#Override
public OutputStream getOutput() throws IOException {
return process.getOutputStream();
}
}, Charsets.UTF_8);
// ok
CharStreams.write(someCommand, writerSupplier);
...
// IOException
CharStreams.write(otherCommand, writerSupplier);

This is definitely expected behavior.
CharStreams.write with an OutputSupplier opens the output stream, writes, and closes it. That's part of the point. Presumably, Process.getOutputStream() doesn't let you open and close more than once.
Either do all the writes at once, or more likely, don't use CharStreams.write and deal with closing the stream yourself.

Related

Keeping output stream open

I wonder how to deal with OutputStreams in codenameone, which have to be kept open for a long time. There are many places, where they get written and it's be neither efficient nor error-proof to try to flush the stream everywhere. So I wrote this:
private boolean needsFlush;
private void write(byte[] data) throws IOException {
assert Display.getInstance().isEdt();
out.write(data);
if (!needsFlush) {
needsFlush = true;
Display.getInstance().callSerially(this::flush);
}
}
private void flush() {
try {
out.flush();
needsFlush = false;
} catch (final IOException e) {
throw new RuntimeException(e); // UGLY!
}
}
which should ensure that after every write, there'll be a flush sometime. Unless the app gets closed or alike.... that's why I need to ask.
Is it OK? Is there's better way of handling stream flushing?
Do they closed then properly, when the app gets terminated?
Do I have to add stream closing code to stop() of the "main" class?
Or only to destroy()?
What about the ugly try-catch?
I would suggest closing the output stream on stop() and re-opening it on start(). Notice that if the stream points to FileSystemStorage you can append to the end of the stream using CN's: OutputStream os = openFileOutputStream(filePath, lengthOfFile);.
You need to close on stop() as the app is sent to the background. In that state you should avoid open connections as they might be terminated suddenly by the OS. The entire app can be killed because of a wayward stream.
If you have background support in the app you should open and close the stream every time you need it.

creating a java wrapper for an inputstream function

I am trying to read a fileinputstream that then gets passed to a calling function which is then played back in a webserver application viewer. The download works fine but the problem is that if I close the stream (which is recommended) within the same function the calling function receives a null stream for some reason. Someone suggested creating an inputstream wrapper and this will allow me to close the stream, delete the file and still pass the stream to the calling function.
public InputStream exportVideo(Youtube connection, String videoID) {
InputStream is = null;
....//file retrieval code above
is = new FileInputStream(ndirectory + "\\" + this.videoID.toString()
+ ".avi");
return is;
....//trace handling code below
finally{
is.close();
}
}
the calling function:
stream = FetchVideo.exportVideo(econnection, videoID);
what I am thinking the suggestion meant was have some class:
public class StreamConverter extends InputStream {
be the wrapper, but I have no idea how to do this.
Any advice or ideas / links on how to do this effectively. Again the problem is closing the stream but being able to pass it on to the calling function.
You should move the is.close() call out of the method and close it where you get it e.g
try {
stream = FetchVideo.exportVideo(econnection, videoID);
//do something with the stream
}
finally {
if (stream != null) {
stream .close();
}
}
or it's better to use try with resource
try (InputStream stream = FetchVideo.exportVideo(econnection, videoID)) {
//do something with the stream
}
You could use composition to implement this InputStream.
Just override all methods so they call your delegate object.
But I am not sure this is the right way to do what you want. I think the best option here is to add an output stream to the function. The function will then write the content it reads to the output stream and the caller is now in charge of closing the stream. (Easy way to write contents of a Java InputStream to an OutputStream)

Reading InputStream from webservice response

What I am trying to do seems to be a quite simple thing, get an InputStream from a Jersey webservice which is returned from a class RestResponse. But I don't get the stream to my client:
public class RestResponse {
private InputStream responseStream;
public RestResponse(InputStream responseBodyStream) throws IOException{
this.responseStream = responseBodyStream;
//here I can get the stream contents from this.responseStream
}
public InputStream getResponseStream() throws IOException {
//here stream content is empty, if called from outside
//only contains content, if called from constructor
return this.responseStream;
}
}
public class HttpURLConnectionClient{
public RestResponse call(){
try{
....
InputStream in = httpURLConnection.getInputStream();
RestResponse rr = new RestResponse(in);
}finally{
in.close(); <- this should be the suspect
}
}
}
RestResponse rr = httpURLConnectionClient.call()//call to some url
rr.getResponseStream(); //-> stream content is empty
Any ideas, what I am missing? Is is not possible to just pipe the stream through?
Certain types of InputStream can only be read once in Java. Based on your comment above, it appears that you are using the InputStream when you pipe it to System.out. Try commenting out the call to System.out and see if you can access your InputStream. Also make sure that the stream is not being consumed anywhere else in the code before the point where you need it.
Update:
It appears that your actual problem was being caused by closing the InputStream before you got a chance to use it. So the solution is to keep the stream open until you need it, and close it afterwards.
Typically, it is not a good design practice to open a stream and keep it open for a long time, because then the underlying resource won't be available to anyone else who needs it. So you should open the stream, and consume it only when you actually need it.

Is it necessary to close each nested OutputStream and Writer separately?

I am writing a piece of code:
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(gzipOutputStream));
Do I need to close every stream or writer like the following?
gzipOutputStream.close();
bw.close();
outputStream.close();
Or will just closing the last stream be fine?
bw.close();
Assuming all the streams get created okay, yes, just closing bw is fine with those stream implementations; but that's a big assumption.
I'd use try-with-resources (tutorial) so that any issues constructing the subsequent streams that throw exceptions don't leave the previous streams hanging, and so you don't have to rely on the stream implementation having the call to close the underlying stream:
try (
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
}
Note you no longer call close at all.
Important note: To have try-with-resources close them, you must assign the streams to variables as you open them, you cannot use nesting. If you use nesting, an exception during construction of one of the later streams (say, GZIPOutputStream) will leave any stream constructed by the nested calls inside it open. From JLS ยง14.20.3:
A try-with-resources statement is parameterized with variables (known as resources) that are initialized before execution of the try block and closed automatically, in the reverse order from which they were initialized, after execution of the try block.
Note the word "variables" (my emphasis).
E.g., don't do this:
// DON'T DO THIS
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new GZIPOutputStream(
new FileOutputStream(createdFile))))) {
// ...
}
...because an exception from the GZIPOutputStream(OutputStream) constructor (which says it may throw IOException, and writes a header to the underlying stream) would leave the FileOutputStream open. Since some resources have constructors that may throw and others don't, it's a good habit to just list them separately.
We can double-check our interpretation of that JLS section with this program:
public class Example {
private static class InnerMost implements AutoCloseable {
public InnerMost() throws Exception {
System.out.println("Constructing " + this.getClass().getName());
}
#Override
public void close() throws Exception {
System.out.println(this.getClass().getName() + " closed");
}
}
private static class Middle implements AutoCloseable {
private AutoCloseable c;
public Middle(AutoCloseable c) {
System.out.println("Constructing " + this.getClass().getName());
this.c = c;
}
#Override
public void close() throws Exception {
System.out.println(this.getClass().getName() + " closed");
c.close();
}
}
private static class OuterMost implements AutoCloseable {
private AutoCloseable c;
public OuterMost(AutoCloseable c) throws Exception {
System.out.println("Constructing " + this.getClass().getName());
throw new Exception(this.getClass().getName() + " failed");
}
#Override
public void close() throws Exception {
System.out.println(this.getClass().getName() + " closed");
c.close();
}
}
public static final void main(String[] args) {
// DON'T DO THIS
try (OuterMost om = new OuterMost(
new Middle(
new InnerMost()
)
)
) {
System.out.println("In try block");
}
catch (Exception e) {
System.out.println("In catch block");
}
finally {
System.out.println("In finally block");
}
System.out.println("At end of main");
}
}
...which has the output:
Constructing Example$InnerMost
Constructing Example$Middle
Constructing Example$OuterMost
In catch block
In finally block
At end of main
Note that there are no calls to close there.
If we fix main:
public static final void main(String[] args) {
try (
InnerMost im = new InnerMost();
Middle m = new Middle(im);
OuterMost om = new OuterMost(m)
) {
System.out.println("In try block");
}
catch (Exception e) {
System.out.println("In catch block");
}
finally {
System.out.println("In finally block");
}
System.out.println("At end of main");
}
then we get the appropriate close calls:
Constructing Example$InnerMost
Constructing Example$Middle
Constructing Example$OuterMost
Example$Middle closed
Example$InnerMost closed
Example$InnerMost closed
In catch block
In finally block
At end of main
(Yes, two calls to InnerMost#close is correct; one is from Middle, the other from try-with-resources.)
You can close the outer most stream, in fact you don't need to retain all the streams wrapped and you can use Java 7 try-with-resources.
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new GZIPOutputStream(new FileOutputStream(createdFile)))) {
// write to the buffered writer
}
If you subscribe to YAGNI, or you-aint-gonna-need-it, you should be only adding code you actually need. You shouldn't be adding code you imagine you might need but in reality doesn't do anything useful.
Take this example and imagine what could possibly go wrong if you didn't do this and what the impact would be?
try (
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
}
Lets start with FileOutputStream which calls open to do all the real work.
/**
* Opens a file, with the specified name, for overwriting or appending.
* #param name name of file to be opened
* #param append whether the file is to be opened in append mode
*/
private native void open(String name, boolean append)
throws FileNotFoundException;
If the file is not found, there is no underlying resource to close, so closing it won't make any difference. If The file exists, it should be throwing a FileNotFoundException. So there is nothing to be gained by trying to close the resource from this line alone.
The reason you need to close the file is when the file is opened successfully, but you later get an error.
Lets look at the next stream GZIPOutputStream
There is code which can throw an exception
private void writeHeader() throws IOException {
out.write(new byte[] {
(byte) GZIP_MAGIC, // Magic number (short)
(byte)(GZIP_MAGIC >> 8), // Magic number (short)
Deflater.DEFLATED, // Compression method (CM)
0, // Flags (FLG)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Extra flags (XFLG)
0 // Operating system (OS)
});
}
This writes the header of the file. Now it would be very unusual for you to be able to open a file for writing but not be able to write even 8 bytes to it, but lets imagine this could happen and we don't close the file afterwards. What does happen to a file if it is not closed?
You don't get any unflushed writes, they are discarded and in this case, there is no successfully written bytes to the stream which isn't buffered at this point anyway. But a file which is not closed doesn't live forever, instead FileOutputStream has
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}
If you don't close a file at all, it gets closed anyway, just not immediately (and like I said, data which is left in a buffer will be lost this way, but there is none at this point)
What is the consequence of not closing the file immediately? Under normal conditions, you potentially lose some data, and you potentially run out of file descriptors. But if you have a system where you can create files but you can't write anything to them, you have a bigger problem. i.e. it hard to imagine why you are repeatedly trying to create this file despite the fact you are failing.
Both OutputStreamWriter and BufferedWriter don't throw IOException in their constructors, so it not clear what problem they would cause. In The case of BufferedWriter, you could get an OutOfMemoryError. In this case it will immediately trigger a GC, which as we have seen will close the file anyway.
If all of the streams have been instantiated then closing only the outermost is just fine.
The documentation on Closeable interface states that close method:
Closes this stream and releases any system resources associated with it.
The releasing system resources includes closing streams.
It also states that:
If the stream is already closed then invoking this method has no effect.
So if you close them explicitly afterwards, nothing wrong will happen.
I'd rather use try(...) syntax (Java 7), e.g.
try (OutputStream outputStream = new FileOutputStream(createdFile)) {
...
}
It will be fine if you only close the last stream - the close call will be send to the underlying streams, too.
No, the topmost level Stream or reader will ensure that all underlying streams / readers are closed.
Check the close() method implementation of your topmost level stream.
In Java 7, there is a feature try-with-resources. You no need to explicitly close your streams, it will take care of that.

Alternative ways to write a file in Java

I have next function:
static void write()
{
try {
File file = new File ("flip.out");
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(sMax);
System.out.println(sMax);//This command it works
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
The problem is that my program doesn't write anything in my file.
Few things to rectify -
Why create two different instances of File object
File file = new File ("flip.out");
BufferedWriter out = new BufferedWriter(new FileWriter("flip.out"));
All you need to do is
File file = new File ("flip.out");
BufferedWriter out = new BufferedWriter(new FileWriterfile(file ) ));
Next put your close call in finally statement rather than try block. Why? Because of IOException occurs resource will not be closed and if resource do not get closed your changes may not be reflected in the file.
Next it is a good programming practice not to catch Runtime exceptions. So do not use Exception as a ploymorphic type to catch your exception. Use whatever is being thrown like IOException in your case.
Now there might be various reasons why noting is being written in the file. As you are not getting and Exception one of the reason why this might be happening because your static function is not getting called or the string/object sMax(whatever that is) is empty.
Also the file(if not already present) will be created in the current directory. So if there are multiple instance is your code where your are creating files with same name then make sure you are checking the right one.
You have to flush the stream in order for what's in the memory to get written to the drive. What you wrote to BufferedWriter is sitting in a byte array waiting for the rest of it to be filled up before actually writing it to the disk. This helps with performance, but means you have to flush the stream in case you don't fill up that buffer. Here is how you do that:
static void write() throws IOException {
BufferedWriter out = new BufferedWriter(new FileWriter("flip.out"));
try {
out.write(sMax);
out.flush();
} catch (Exception e) {
// probably could ditch this and
// just the exception bubble up and
// handle it higher up.
e.printStackTrace();
} finally {
out.close();
}
}
So if it makes it to the flush() we know we wrote everything to the stream we wanted. However, if we ever get an exception we make sure we close the stream regardless of success or exception. And finally our stream is outside the try statement because the only exception ever thrown by Writers/OutputStreams during construction is FileNotFoundException which means the file never got opened in the first place so we don't have to close it.
can you call out.flush() before closing.
that will make sure any content in buffer is written to file immediately.

Categories

Resources