ObjectInputStream throwing exception on read - java

I'm having difficulty with ObjectInputStream. I wrote a simple test which fails on the read with an EOF error. Any input would be greatly appreciated.
public class Test
{
#Test
public void testObjectStreams( ) throws IOException, ClassNotFoundException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
String stringTest = "TEST";
oos.writeObject( stringTest );
oos.close();
baos.close();
byte[] bytes = baos.toByteArray();
String hexString = DatatypeConverter.printHexBinary( bytes);
byte[] reconvertedBytes = DatatypeConverter.parseHexBinary(hexString);
assertArrayEquals( bytes, reconvertedBytes );
ByteArrayInputStream bais = new ByteArrayInputStream(reconvertedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
String readString = (String) ois.readObject();
assertEquals( stringTest, readString);
}
}

Related

How to write serializable object to String without writing to file?

I want to write a class object to the string and then again create an object from it.
I searched on the net but all I found is to write an object to file however I want to write in the string, not on file.
Below is the example of writing to file similarly I want to write in String or similar Object and not in the file.
some_class implements serializable {
...
}
FileOutputStream f = new FileOutputStream(new File("myObjects.txt"));
ObjectOutputStream o = new ObjectOutputStream(f);
// Write objects to file
o.writeObject(object1);
o.close();
f.close();
FileInputStream fi = new FileInputStream(new File("myObjects.txt"));
ObjectInputStream oi = new ObjectInputStream(fi);
// Read objects
some_class object2 = (some_class) oi.readObject();
oi.close();
fi.close();
Please help with the same.
This would be one way:
try
{
// To String
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(object1);
String serializedObject1 = bos.toString();
os.close();
// To Object
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject1.getBytes());
ObjectInputStream oInputStream = new ObjectInputStream(bis);
YourObject restoredObject1 = (YourObject) oInputStream.readObject();
oInputStream.close();
} catch(Exception ex) {
ex.printStackTrace();
}
I would prefer the Base64 way though.
This would be an example of encoding:
private static String serializableToString( Serializable o ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
And this is an example of decoding:
private static Object objectFromString(String s) throws IOException, ClassNotFoundException
{
byte [] data = Base64.getDecoder().decode(s);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data));
Object o = ois.readObject();
ois.close();
return o;
}
the best way to serialize an object to String and vice versa you should convert the object into JSON String and encode into base64. and to get object decode base64 and convert to object using GSON (opensource google provide java library)
class foo{ String name, email;
//setter getter
}
convert Object to base64 JSON
public static String convertToJson(Object o){
String result=new Gson().toJson(o);
return Base64.getEncoder().encodeToString(result);
}
//read base64
public static <T> T convertJsonToObject(String base64Object,Class<T> classOfT){
Gson gson = new Gson();
return gson.fromJson(new InputStreamReader(new ByteArrayInputStream(Base64.getDecoder().decode(base64Object))),classOfT);
}
public static void main(String[] args) {
foo obj=new foo("jhon","jhon#gamil.com");
String json=convertToJson(foo);
System.out.println(json);
foo obj_fromJson=convertJsonToObject(json,foo.class);
System.out.println(obj_fromJson.getName());
}

UDP datagram is sent but never received

I made two different java classes, for a client and for a server, with send and receive methods in each. According to the task, I had to make server-to-client connection via DatagramPacket and client-to-server via DatagramChannel. The last one works great, but I have trouble with datagrams -- they are sent from the server and never received on the client. What's wrong?
public class TransferClient implements Serializable{
private static final long serialVersionUID = 26L;
public TransferClient() {
}
public void send(Command com) throws IOException {
SocketAddress socketAddressChannel = new InetSocketAddress("localhost", 1);
DatagramChannel datagramChannel=DatagramChannel.open();
ByteBuffer bb;
datagramChannel.connect(socketAddressChannel);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(com);
oos.flush();
bb=ByteBuffer.wrap(baos.toByteArray(),0, baos.size());
datagramChannel.send(bb,socketAddressChannel);
baos.close();
oos.close();
}
public Command receive() throws IOException, ClassNotFoundException {
SocketAddress address = new InetSocketAddress(2029);
DatagramSocket s = new DatagramSocket();
DatagramPacket inputPacket = new DatagramPacket(new byte[1024],1024, address);
s.receive(inputPacket);
ByteArrayInputStream bais = new ByteArrayInputStream(inputPacket.getData());
ObjectInputStream ois = new ObjectInputStream(bais);
return (Command) ois.readObject();
}
}
public class TransferServer {
public TransferServer(){
}
public void send(Command com) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
byte[] buffer;
oos.writeObject(com);
oos.flush();
buffer=baos.toByteArray();
SocketAddress address = new InetSocketAddress("localhost",2029);
DatagramSocket s = new DatagramSocket();
DatagramPacket outputPacket = new DatagramPacket(buffer,buffer.length,address);
s.send(outputPacket);
}
public Command receive() throws IOException, ClassNotFoundException {
SocketAddress socketAddressChannel = new InetSocketAddress("localhost", 1);
DatagramChannel datagramChannel = DatagramChannel.open();
datagramChannel.bind(socketAddressChannel);
ByteBuffer bb = ByteBuffer.allocate(1024);
datagramChannel.receive(bb);
ByteArrayInputStream bais = new ByteArrayInputStream(bb.array());
ObjectInputStream ois = new ObjectInputStream(bais);
Command command;
System.out.println(ois.available());
command =(Command) ois.readObject();
datagramChannel.close();
ois.close();
bais.close();
return command;
}
}
You have to specify the port on which to bind your DatagramSocket in order to receive your data. Otherwise it will bind to the first available port found on your machine.
And you don't need the SocketAddress here, but you do need to take account of the actual received packet length.
See java.net.DatagramSocket Documentation
In the receive() method of your TransferClient class:
public Command receive() throws IOException, ClassNotFoundException {
DatagramSocket s = new DatagramSocket(2029); //Add your port Here
DatagramPacket inputPacket = new DatagramPacket(new byte[1024],1024);
s.receive(inputPacket);
ByteArrayInputStream bais = new ByteArrayInputStream(inputPacket.getData(), 0, packet.getLength());
ObjectInputStream ois = new ObjectInputStream(bais);
return (Command) ois.readObject();
}

Java - How to do Gzip compression of java object

How to compress a Java pojo object using Gzip?
Below code compress a string -
public static String compress(String str, String inEncoding) {
if (str == null || str.length() == 0) {
return str;
}
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes(inEncoding));
gzip.close();
return URLEncoder.encode(out.toString("ISO-8859-1"), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Instead of String str as a parameter, how to use below pojo class object (Client cc) and compress?
Pojo class -
Class client {
Public string name;
Public string location;
//Getter and setter methods
}
How can i compress and decompress this client pojo class using gzip.?
You can compress your Client class which implements serializable using gzip by doing the following :
public static bytes[] compressThis(Client client){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzipOut = new GZIPOutputStream(client);
ObjectOutputStream objectOut = new ObjectOutputStream(gzipOut);
objectOut.writeObject(client);
objectOut.close();
return baos.toByteArray();
}
Following which you can decompress it by doing the following :
public static getClientFrom(bytes[] bytes){
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
GZIPInputStream gzipIn = new GZIPInputStream(bais);
ObjectInputStream objectIn = new ObjectInputStream(gzipIn);
Client client = (Client) objectIn.readObject();
objectIn.close();
return client;
}

convert pdf to byteArray - byteArray to String - String to byteArray - byteArray to pdf

I have the following code which works for text files but doesn't work for pdf files. My files contain english and greek characters. I try to convert a pdf file to byteStream and the byteStream to String format in order to save it in database. After this I try to create the pdf from the saved String.
Any help?
public class PdfToByteStream {
public static byte[] convertDocToByteArray(String path)throws FileNotFoundException, IOException{
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
}
} catch (IOException ex) {
Logger.getLogger(genJpeg.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] bytes = bos.toByteArray();
return bytes;
}
public static void convertByteArrayToDoc(String path, byte[] bytes)throws FileNotFoundException, IOException {
File someFile = new File(path);
FileOutputStream fos = new FileOutputStream(someFile);
fos.write(bytes);
fos.flush();
fos.close();
}
public static void main(String[] args) throws FileNotFoundException, IOException {
byte[] bytes = convertDocToByteArray("path/test.pdf");
String stream = new String(bytes, "UTF-8");//ok for txt
byte[] newBytes = stream.getBytes(Charset.forName("UTF-8")); // ok for txt
convertByteArrayToDoc("path/newTest.pdf", newBytes);
}
}
If you use Base64 encoding you will be able to convert the PDF to a string and back.
Here is the relevant part of the code which needs to be changed:
import java.util.Base64;
...
public static void main(String[] args) throws FileNotFoundException, IOException {
byte[] bytes = convertDocToByteArray("some.pdf");
String stream = Base64.getEncoder().encodeToString(bytes);
byte[] newBytes = Base64.getDecoder().decode(stream);
convertByteArrayToDoc("some_new.pdf", newBytes);
}

Serialization and archiving object

I need to do the same operation but in one stream. May you help me, please?
public static byte[] archivingAndSerialization(Object object){
ByteArrayOutputStream serializationByteArray = new ByteArrayOutputStream();
ByteArrayOutputStream archvingByteArray = new ByteArrayOutputStream();
try {
ObjectOutputStream byteStream = new ObjectOutputStream(serializationByteArray);
byteStream.writeObject(object);
ZipOutputStream out = new ZipOutputStream(archvingByteArray);
out.putNextEntry(new ZipEntry("str"));
out.write(serializationByteArray.toByteArray());
out.flush();
out.close();
} catch (IOException e) {
logger.error("Error while IOException!", e);
}
return archvingByteArray.toByteArray();
}
Try
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos= new ObjectOutputStream(new DeflatingOutputStream(baos));
oos.writeObject(object);
oos.close();
return baos.toByteArray();
Note: Unless the object is medium to large in size, compressing it will make it bigger, as it add a header. ;)
To deserialize
ObjectInputStream ois = new ObjectInputStream(
new InflatorInputStream(new ByteArrayInputStream(bytes)));
return ois.readObject();

Categories