Java - Concatenating Two OutputStreams - java

Is it possible to concatenate two OutputStreams (of the same type, stored as OutputStreams) without converting either to a string? If so, how?

So, If you have OutputStream A, and OutputStream B, and you want to concatenate them so that you end up with the stuff from A, followed by the stuff from B, you could convert B into an InputStream (a task that has likely been explained over 9000 times in this forum), and then Read data from this new InputStream, and write it to A. There: A generic answer for a generic question. Good luck!

A short example:
private void test(Document xmlDoc) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
String s1 = "header";
outputStream.write(s1.getBytes());
ByteArrayOutputStream bodySubTree = (ByteArrayOutputStream) xmlToOutStream(xmlDoc);
outputStream.write(bodySubTree.toByteArray());
String s2 = "footer";
outputStream.write(s2.getBytes());
}

Related

Java write a byte array with given ObjectOutputStream

I have a serializable class with custom writeObject() and readObject() methods.
When an object serializes, it needs to write two byte arrays, one after another. When something deserializes it, it needs to read those two arrays.
This is my code:
private void writeObject (final ObjectOutputStream out) throws IOException {
..
out.writeByte(this.signature.getV()); //one byte
out.writeObject(this.signature.getR()); //an array of bytes
out.writeObject(this.signature.getS()); //an array of bytes
out.close();
}
private void readObject (final ObjectInputStream in) throws IOException, ClassNotFoundException {
..
v = in.readByte();
r = (byte[])in.readObject();
s = (byte[])in.readObject();
this.signature = new Sign.SignatureData(v, r, s); //creating a new object because
//sign.signaturedata
// is not serializable
in.close();
}
When the object is being deserialized (readObject method) it throws an EOFException and all three variables are null/undefined.
Relating to question title, I saw a class called ByteArrayOutputStream, but to use it, it has to be enclosed in a ObjectOutputStream, which I cannot do, ad I have an OutputStream given and must write with it.
1. How do one properly write a byte array using objectOutputStream and properly reads it using ObjectInputStream?
2. Why the code above throws an EOFException without reading even one variable?
EDIT: I need to clarify: the readObject() and writeObject() are called by jvm itself while deserializing and serializing the object.
The second thing is, the SignatureData is a subclass to Sign, that comes from a third-party library - and that's why it's not serializable.
The third thing is, the problem probably lies in the reading and writing byte arrays by ObjectInput/ObjectOutput streams, not in the Sign.SignatureData class.

converting outputStream to byte array [duplicate]

This question already has answers here:
How to convert outputStream to a byte array?
(5 answers)
Closed 5 years ago.
How can I get the bytes of an outputStream, or how can I convert an outputStream to a byte array?
From a theoretical perspective (i.e., irrespective of whether it makes sense in practice as a use case), this is an interesting question that essentially requires the implementation of a method like
public abstract byte[] convert(OutputStream out);
The Java OutputStream class, as its name implies, only supports an overridden write() method for I/O, and that write() method gets either an integer (representing 1 byte) or a byte array, the contents of which it sends to an output (e.g., a file).
For example, the following code saves the bytes already present in the data array, to the output.txt file:
byte[] data = ... // Get some data
OutputStream fos = new FileOutputStream("path/to/output.txt");
fos.write(data);
In order to get all the data that a given OutputStream will be outputting and put it into a byte array (i.e., into a byte[] object), the class from which the corresponding OutputStream object was instantiated, should keep storing all the bytes processed via its write() methods and provide a special method, such as toByteArray(), that would return them all, upon invocation.
This is exactly what the ByteArrayOutputStream class does, making the convert() method trivial (and unnecessary):
public byte[] convert(ByteArrayOutputStream out) {
return out.toByteArray();
}
For any other type of OutputStream, not inherently supporting a similar conversion to a byte[] object, there is no way to make the conversion, before the OutputStream is drained, i.e. before the desired calls to its write() methods have been completed.
If such an assumption (of the writes to have been completed) can be made, and if the original OutputStream object can be replaced, then one option is to wrap it inside a delegate class that would essentially "grab" the bytes that would be supplied via its write() methods. For example:
public class DrainableOutputStream extends FilterOutputStream {
private final ByteArrayOutputStream buffer;
public DrainableOutputStream(OutputStream out) {
super(out);
this.buffer = new ByteArrayOutputStream();
}
#Override
public void write(byte b[]) throws IOException {
this.buffer.write(b);
super.write(b);
}
#Override
public void write(byte b[], int off, int len) throws IOException {
this.buffer.write(b, off, len);
super.write(b, off, len);
}
#Override
public void write(int b) throws IOException {
this.buffer.write(b);
super.write(b);
}
public byte[] toByteArray() {
return this.buffer.toByteArray();
}
}
The calls to the write() methods of the internal "buffer" (ByteArrayOutputStream) precede the calls to the original stream (which, in turn, can be accessed via super, or even via this.out, since the corresponding parameter of the FilterOutputStream is protected). This makes sure that the bytes will be buffered, even if there is an exception while writing to the original stream.
To reduce the overhead, the calls to super in the above class can be omitted - e.g., if only the "conversion" to a byte array is desired. Even the ByteArrayOutputStream or OutputStream classes can be used as parent classes, with a bit more work and some assumptions (e.g., about the reset() method).
In any case, enough memory has to be available for the draining to take place and for the toByteArray() method to work.
For #Obicere comment example:
ByteArrayOutputStream btOs = new ByteArrayOutputStream();
btOs.write("test bytes".getBytes());
String restoredString = new String(btOs.toByteArray());
System.out.println(restoredString);

To Find Java Object Size using serialization

I have been struggling for finding the exact size of java objects. I have tried different options and non of them are working correctly. Then I tried to serialize the object and find the size of the serialized object. The size of the serialized object is very small, like in few kilo byte. So I doubted my method. I was wondering is it the correct way? Is there any problem you people see in this procedure? Please help...
You can convert your object into a byte array using ObjectOutputStream and ByteArrayOutputStream:
public static int sizeof(Object obj) throws IOException {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
objectOutputStream.writeObject(obj);
objectOutputStream.flush();
objectOutputStream.close();
return byteOutputStream.toByteArray().length;
}

What is the difference between write and writeInt?

When writing to a file using an OuputStream, what is the difference between using writeInt():
public static void makeFile(String name) throws Exception{
try (
OutputStream ostr = new FileOutputStream(name); ) {
//Uses writeInt() method
ostr.writeInt(1);
ostr.close();
}
}
and using write():
public static void makeFile(String name) throws Exception{
try (
OutputStream ostr = new FileOutputStream(name); ) {
// Uses the write() method with an int as input
ostr.write(1);
ostr.close();
}
}
What do both methods mean?
writeInt is not a member of OutputStream, so it wont compile. Assuming you use DataOutputStream or similar it will write the four bytes of the 32-bit integer in big-endian order. write will just write a single byte (the least significant of the int).
Arguably it wasn't a great idea to mix these two different ideas in the same interface. DataOutputStream should not have extended OutputStream, but too late to fix that now.
writeInt(int) comes from DataOutput interface. (ObjectOutputStream implements ObjectOutput interface, and ObjectOutput interface extends DataOutput interface.) As you can see from the JavaDoc documentation for DataOutput writeInt method, it writes four bytes in big endian order to the underlying stream.
write(int) comes from OutputStream class, which is extended by ObjectOutputStream. This method writes the low order byte of the int argument (the "right most" eight bits). Again, you can see this in the JavaDoc documentation.

How to send a string array using sockets and objectoutputstream

I have this to send string or integer but if i want to send a string array what should i use?
// A string ("Hello, World").
out.write("Hello, World".getBytes());
// An integer (123).
out.write(ByteBuffer.allocate(4).putInt(123).array());
Thanks in advance
Just write the array
ObjectOutputStream out = ...
String[] array = ...
out.writeObject(array);
If you're using ObjectOutputStream, there's no need to muck about with byte arrays - the class provides high-level methods to read and write entire objects.
Similarly:
out.writeInt(123);
out.writeObject("Hello, World");
You only need to use the write(byte[]) methods if you're using the raw, low-level OutputStream class.

Categories