update in java9: https://docs.oracle.com/javase/9/docs/api/java/io/InputStream.html#transferTo-java.io.OutputStream-
I saw some similar, but not-quite-what-i-need threads.
I have a server, which will basically take input from a client, client A, and forward it, byte for byte, to another client, client B.
I'd like to connect my inputstream of client A with my output stream of client B. Is that possible? What are ways to do that?
Also, these clients are sending each other messages, which are somewhat time sensitive, so buffering won't do. I do not want a buffer of say 500 and a client sends 499 bytes and then my server holds off on forwarding the 500 bytes because it hasn't received the last byte to fill the buffer.
Right now, I am parsing each message to find its length, then reading length bytes, then forwarding them. I figured (and tested) this would be better than reading a byte and forwarding a byte over and over because that would be very slow. I also did not want to use a buffer or a timer for the reason I stated in my last paragraph — I do not want messages waiting a really long time to get through simply because the buffer isn't full.
What's a good way to do this?
transferTo() Method. In Java 9 or higher, you can use the InputStream. transferTo() method to copy data from InputStream to OutputStream . This method reads all bytes from this input stream and writes the bytes to the given output stream in the original order.
InputStream is; byte[] bytes = IOUtils. toByteArray(is); Internally this creates a ByteArrayOutputStream and copies the bytes to the output, then calls toByteArray() . It handles large files by copying the bytes in blocks of 4KiB.
The InputStream is used to read data from a source and the OutputStream is used for writing data to a destination.
Methods of InputStreamread() - reads one byte of data from the input stream. read(byte[] array) - reads bytes from the stream and stores in the specified array. available() - returns the number of bytes available in the input stream. mark() - marks the position in the input stream up to which data has been read.
Just because you use a buffer doesn't mean the stream has to fill that buffer. In other words, this should be okay:
public static void copyStream(InputStream input, OutputStream output) throws IOException { byte[] buffer = new byte[1024]; // Adjust if you want int bytesRead; while ((bytesRead = input.read(buffer)) != -1) { output.write(buffer, 0, bytesRead); } }
That should work fine - basically the read
call will block until there's some data available, but it won't wait until it's all available to fill the buffer. (I suppose it could, and I believe FileInputStream
usually will fill the buffer, but a stream attached to a socket is more likely to give you the data immediately.)
I think it's worth at least trying this simple solution first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With