Piping a FileOutputStream to an InputStream without disk i/o - java

A third party library casts my SubClassOfOutputStream to a FileOutputStream internally to invoke the getChannel() operation even though they expose an OutputStream interface in their API. This (obviously) causes a ClassCastException.
I need to write to a SubClassOfOutputStream interface. I clearly need to write to a FileOutputStream container, pipe that data to an InputStream, and read bytes from the InputStream in question into my SubClassOfOutputStream instance. Is there a way to do this without disk i/o?
Thanks!

Related

drain() vs flush() in ObjectOutputStream Class in Java

When I saw descriptions about these two methods as below, I felt a bit confused about them.
protected void drain(): Similar to flush but does not propagate the flush to the underlying stream.
void flush(): Writes any buffered output bytes and flush through to the underlying stream.
For example:
FileOutputStream out = new FileOutputStream("test.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
Question 1:
If I call oout.flush(), it will force the output data in the ObjectOutputStream to be written to the underlying FileOutputStream, but it doesn't guarantee that these data will be subsequently written from FileOutputStream to the file "test.txt" in the disk since I don't call out.flush(), is this correct?
Question 2:
What if I call oout.drain()?
What executions will be done?
Question 1:
If I call oout.flush(), it will force the output data in the ObjectOutputStream to be written to the underlying FileOutputStream, but it doesn't guarantee that these data will be subsequently written from FileOutputStream to the file "test.txt" in the disk since I don't call out.flush(), am I right?
No, you are wrong. It does flush the FileOutputStream. However, as FileOutputStream doesn't buffer or flush, in fact there is no difference between drain() and flush() in this circumstance. If there had been a BufferedOutputStream around the FileOutputStream, there would have been a difference.
Question 2:
What if I call oout.drain()? What executions will be done?
It will flush the ObjectOutputStream but not the underlying stream, exactly as it says in the Javadoc.
You have somehow managed to get this completely back to front. I can't understand how: the Javadoc is quite clear. Also, as drain() is protected it is none of your business anyway.
Flush will write the data to the test.txt. However, drain is similar to flush but does not propagate the flush to the underlying stream.

answer for necessity of flush in I/O streams in java in fileoutputstreams

Hi I need a answer for necessity of flush in I/O streams in java.since in my program with flush and without flush the output is same.ie,every thing is written in to the destination file.then why i need flush?will file input stream consumes buffer memory?
the below is my simple sample program
file = new File("c:/newfile.txt");
fop = new FileOutputStream("c:/newfile.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
even when i command flush and close it can write the contents in to the file properly..?then y we need flush?and will file outputstream consumes memory?
Close calls flush on the stream, so flush is not needed if you want to close the stream.
Flush is useful if you want to make sure that the data is saved, without closing a stream, e.g. when sending messages over the Internet, or writing to the console. You may notice, that if you write to console with system.out.print(), then the output is not displayed, until you call flush, or until there is a new line in the text (in which case Java will call flush for you).
See more on this question
In fact, FileOutputStream is not buffered, so the data is directly written to the file.
The abstract OutputStream defines flush (an empty method) to accomodate also the needs of buffered streams, so FileOutputStream inherits it.
If you are not certain of the underlying implementation, it is generally good practice to flush the streams before closing them.
Also, in your code there is a little error:
file = new File("c:/newfile.txt");
fop = new FileOutputStream("c:/newfile.txt");
// Will never happen, new FileOutputStream creates the file
if (!file.exists()) {
file.createNewFile();
}
EDIT:
As for the close part of the question:
When you comment out close(), then exiting main() the close method is called by the finalizer (i.e before the stream is garbage collected, a JVM thread calls its finalize() method, which in turn calls the close() method), but you can't sensibly rely on the finalizer: you don't own it and you can't be sure of when it is activated.
Again , best practice is to call close() explicitly.

Sending objects through Java NIO non-blocking sockets

I am getting an exception when trying to use:
oos = new ObjectOutputStream(socketChannel.socket().getOutputStream());
oos.writeObject(o);
And this raises the exception:
java.nio.channels.IllegalBlockingModeException
Is it impossible to pass objects in non-blocking sockets?
If it is, how should I proceed on passing message objects through the socket channels?
I've looked other places for this answer but couldn't find one...
You'll probably want to write your own ObjectOutputStream implementation that constructs a ByteBuffer and write()s it to the channel.
With non-blocking sockets, you cannot directly use the channel's socket; you need to use the channel's read() and write() methods.
When you write your own ObjectOutputStream, you'll mainly need to override the write() methods to buffer output and use the flush() method to write the buffer to the channel. Then, override the writeObject() method to look like this:
public void writeObject(Object o) throws IOException {
super.writeObject(o);
flush();
}
to make sure the data gets written after each object write.
It's been a while since I worked in this area but it seemed to be more complex than simply wrapping writeObject. java.nio typically expects fixed size buffers (though you can dynamically allocate them I believe) and your remote endpoints need to know how much to read for an arbitrary Object coming down the wire. What I ended up doing was to send an initial int header telling the other end how much data to expect, and then serializing the object to a byte array and sending that down the wire.
I've got an example of this that may still have some bugs, so use at your own risk. The PendingDataBufferS are needed to deal with objects that are larger than the initially allocated fixed size buffer.

Have you ever seen a Java File close() throw an exception?

Has anyone ever seen an exception thrown when calling close method on any closable object?
An IOException will be thrown on close if the final flush fails. Possible causes include:
the file system is full, or the user is over quota,
hard disc errors,
a file system was forcibly unmounted,
a remote file system is unavailable due to networking or other problems,
(possibly) a character encoding error if writing to the file via an OutputStreamWriter or similar,
a device error if the "file" is a device file,
a lost connection if the closeable is a network stream,
a broken pipe if the closeable is a pipe to external process,
and so on.
I have certainly seen some of these. Others are unlikely.
However, if the data you are writing is important then you should allow for close failing. For example, if your application is writing out a critical file the file system fills up, your application had better notice this before it replaces the old copy of the file with the truncated version.
Yes, it's not that rare, IMHO if you are working with anything other than non-local disk files.
Close() works if at that point your closable is still valid and open. Many things like pipes, remote files, etc., can die prematurely.
In addition, I have seen code that ignores errors on open and write and still tries to close (e.g., in a finally block).
Not in terms of file-io, but in terms of sockets the close will raise IOException when the other side has aborted the connection. For example, when you fire a HTTP request on a (large) webpage and then immediately navigate away by clicking another link on the webpage (while it isn't finished loading), then the server side will get an IOException (or a subclass like ClientAbortException in Tomcat servers and clones) when the outputstream of the HTTP response is to be flushed/closed.
Old post and long since answered but here's a real example:
The following code will except out when bufferedWriter.close() is called. This happens because the BufferedWriter's underlying Writer (the FileWriter) has already been closed and when a BufferedWriter closes, it first attempts to flush any data in its buffer to its underlying Writer.
File newFile = new File("newFile.txt");
FileWriter fileWriter = new FileWriter(newFile);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("Hello World");
fileWriter.close();
bufferedWriter.close();
Note: If there's no data in the buffer [comment out the write() line or add a flush() call] then no exception will be generated
I haven't, but it's possible. Imagine if there's an OutputStream that for some reason hasn't written to the file yet. Well, calling close() will flush out the data, but if the file is locked - then an IOException would be raised.
Try yanking a USB drive with an open file on it. If it doesn't give an exception I'd be pretty surprised.
I guess you could try to force this by unplugging the disk your file is on. But on any Closable? I think it would be easy to get something that uses a socket to throw an exception upon closing.
I have - in my unit tests against mocks ;)

Does closing a BufferedOutputStream also close the underlying OutputStream?

I am streaming binary data (a CSV file extracted from the database as a Clob) to the browser by calling response.getOutputStream() and would normally wrap the OutputStream in a BufferedOutputStream when copying the data.
Should I close the BufferedOutputStream or will this also close the underlying OutputStream?
[Extra question: Do I need to use a BufferedOutputStream in this case or is the response already buffered?]
Yes, it closes it. As for whether you should close it - are you expecting to write anything else to the response stream? If not, I think it's fine to close it. If you don't close it, you should obviously flush it instead - but I suspect you could figure that bit out for yourself :)
The behaviour is actually inherited from FilterOutputStream. The Javadocs for for FilterOutputStream.close state:
The close method of FilterOutputStream
calls its flush method, and then calls
the close method of its underlying
output stream.
As for whether you should buffer it - I'm not sure that this is well defined. It may be buried in the servlet spec somewhere - and it may even be configurable (sometimes you really don't want buffering, but if you can buffer the whole response it means you can serve a nicer error page if things go wrong after you've started writing).
Closing the BufferedOutputStream will also close the underlying OutputStream. You should close the BufferedOutputStream so that it flushes its contents before closing the underlying stream. See the implementation of FilterOutputStream.close() (from which BufferedOutputStream extends) to convince yourself.
I guess that whether or not the response stream given to your servlet is buffered or not depends on the implementation of your Servlet Container. FWIW I know that Tomcat does buffer its servlet response streams by default, in order to attempt to set the content-length HTTP header.

Categories

Resources