I am looking to implement a HashMap with its contents in the bytecode. This would be similar to me serializing the content and then reading it in. But in my experience serialization only works with saving it to a file and then reading it in, I would want this implementation to be faster than that.
But in my experience serialization only works with saving it to a file and then reading it in, I would want this implementation to be faster than that.
Serialization works with streams. Specifically, ObjectOutputStream can wrap any OutputStream. If you want to perform in-memory serialization, you could use ByteArrayOutputStream here.
Similarly on the input side.
You can save your HashMap as byte array using Java Serialization mechanizm
Map map = new HashMap();
map.put(1, 1);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(map);
oos.close();
byte[] bytes = bout.toByteArray();
// restore from bytes
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
map = (Map) ois.readObject();
System.out.println(map);
output
{1=1}
not that both keys and values in the Map must be Serializable otherwise it wont work
Related
I need to save a pdf document, generated by aspose.pdf for java library to memory (without using temporary file)
I was looking at the documentation and didn't find the save method with the appropriate signature. (I was looking for some kind of outputstream, or at least byte array).
Is it possible? If it is, how can I manage that?
Thanks
Aspose.Pdf for Java supports saving output to both file and stream. Please check following code snippet, It will help you to accomplish the task.
byte[] input = getBytesFromFile(new File("C:/data/HelloWorld.pdf"));
ByteArrayOutputStream output = new ByteArrayOutputStream();
com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(new ByteArrayInputStream(input));
pdfDocument.save(output);
//If you want to read the result into a Document object again, in Java you need to get the
//data bytes and wrap into an input stream.
InputStream inputStream=new ByteArrayInputStream(output.toByteArray());
I am Tilal Ahmad, developer evangelist at Aspose.
I did similar thing.
Here is method to write data to byte:
public byte[] toBytes() {
//create byte array output stream object
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
//create new data output stream object
DataOutputStream outStream = new DataOutputStream(byteOutStream);
try {//write data to bytes stream
if (data != null) {
outStream.write(data);//write data
}//return array of bytes
return byteOutStream.toByteArray();
}
Then you do something like
yourFileName.toBytes;
I am just trying to understand the wrapping of an array of bytes using ByteArrayInputStream class. Here is the code that I have doubt about it.
byte[] bytes = new byte[1024];
//write data into byte array...
InputStream input = new ByteArrayInputStream(bytes);
//read first byte
int data = input.read();
while(data != -1) {
//do something with data
//read next byte
data = input.read();
}
My question is it it possible to write this part
InputStream input = new ByteArrayInputStream(bytes);
like this
ByteArrayInputStream input = new ByteArrayInputStream(bytes);
And why the author of this code created the object with both the super and sub classes?
I really thank you for your help.
Yes, you can write
InputStream input = new ByteArrayInputStream(bytes);
like
ByteArrayInputStream input = new ByteArrayInputStream(bytes);
It is functionally the same.
However, in OOP it's widely recommended to "program to interfaces". See What does it mean to "program to an interface"? for an explanation.
In this case, strictly speaking, InputStream is not an interface, but an abstract superclass. However, it more or less acts like an interface.
is it it possible to write this part
(InputStream input = new ByteArrayInputStream(bytes);)
like this
( ByteArrayInputStream input = new ByteArrayInputStream(bytes);)
Certainly. Why do you think otherwise? What happened when you tried it? Why are you using StackOverflow as a substitute for conclusive experiments?
And why the author of this code created the object with both the super and sub classes?
He didn't. He created the object as an instance of ByteArrayInputStream. He then assigned the result to a variable of type InputStream. It's perfectly normal.
I'm crating a client-server chat application. After discovering the C/C++ approach with sending bytes of data is a real pain in Java (signed bytes are simply hilarious), I started trying to use more convenient methods - specifically Serializable interface and ObjectOutputStream along with ByteArrayOutputStream.
This answer quite describes what I know at the moment.
So, I can convert my object into a byte array, which can then be put into output buffer that is eventually sent (the sending is done asynchronously).
Now with object, I need to send the size of the byte array first - so that the receiving function knows how much data should be read before parsing the object.
So in this code:
out = new ObjectOutputStream(bos);
out.writeObject(this);
return bos.toByteArray();
Can I somehow prepend the object size?
out = new ObjectOutputStream(bos);
out.writeObject(this);
//PSEUDO FUNCTION - beware
out.writeIntOnOffset(out.size(), 0) //Push the size on the beginning of the array
return bos.toByteArray();
Once you have object size just send it:
MyClass obj = ....;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj); // this is what you already have.
int size = baos.length; // now we have size
OutputStream socketStream = .... // I guess you know how to get it.
ObjectOutputStream socketOos = new ObjectOutputStream(socketStream);
socketOos.writeInt(size);
socketOos.write(baos.toByteArray());
You should definitely not mess with the array it self.
Instead you should create a separate method that returns size
I need to store a binary object (java class having several collections inside) in the key-value storage.
The size limit for the value is 4K.
I created XStream based serializer and deserializer, so when I am done filling my class members I can serialize it to a String or to a file.
In the worst case the serialized String/file size is ~30K. I mange to achive good compression rate so after compression my file is ~2K which fits the bill.
My question: is there any useful java API\library\technique that can:
compress a String and serialize the compressed object.
decompress previously compressed object and create a regular String from it
I am looking for one-liners that do not require intermediate storage of serialized object to file for later compression.
Appreciate your help!
Try a GZIPOutputStream for zipping the String:
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(out)));
writer.write(string);
byte[] zipped = out.toByteArray();
And to unzip again:
ByteArrayInputStream in = new ByteArrayInputStream(zipped);
BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(in)));
string = reader.readLine();
I want to create on ObjectOutputStream, but I don't want to persist the object in a file, so how to do that? All the tutorials(that I found) say only about the file way:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new Date());
oos.close();
I want to store the object into a database, so I need to specify a stream in method setBinaryStream() from class PreparedStatement.
Thanks for answering...
Store it in a byte array instead. You can use ByteArrayOutputStream for this. This way you can use PreparedStatement#setBytes().
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new Date());
oos.close();
// ...
preparedStatement.setBytes(i, baos.toByteArray());
That said, this is pretty a good smell. Are you sure that you need to serialize Java objects into a database? This way they are unindexable and unsearchable. If you for example store each Person serialized in the DB, you cannot do SELECT * FROM person WHERE name = 'John' anymore. The normal practice is to do a 1:1 mapping of the entity and the DB table. The Date for example can perfectly be stored in a DATETIME/TIMESTAMP column.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(new Date());
os.close();
byte[] data = bos.toByteArray();
So now you have a byte array and do what you want with it.
you specifically need to use an outputstream to write to a database? I would seriously consider looking at the persistence api before attempting to write an outputstream implementation.. since connection details etc, might get tricky to manage.
have a look at link text and remember it can be used in J2SE as well.