Move "Cursor" of readObject (Stop reading the same object) - java

There are 3 objects in the "or" file. The loop returns the same object over and over again and I do not know how to tell the readObject() to move onto the next object.
import java.io.*;
import java.util.*;
public class Mainclass {
public static void main(String[] args) {
int l = 1;
while (l > 0) {
try {
InputStream is = new FileInputStream("or.rtf");
ObjectInputStream ois = new ObjectInputStream(is);
Stone p = (Stone) ois.readObject();
System.out.println(p);
ois.close();
} catch(Exception e) {
if(e instanceof EOFException) {
l--;
System.err.println();
} else if(e instanceof FileNotFoundException) {
l--;
System.err.println(e);
} else {
System.err.println(e);
}
}
}
}
}
EDIT: New code looks like this:
import java.io.*;
import java.util.*;
public class Mainclass {
public static void main(String[] args) {
InputStream is;
try {
is = new FileInputStream("or.rtf");
ObjectInputStream ois;
try {
ois = new ObjectInputStream(is);
int l = 1;
while (l > 0) {
try {
Stone p = (Stone) ois.readObject();
System.out.println(p);
ois.close();
} catch(Exception e) {
if(e instanceof EOFException) {
l--;
System.err.println();
} else if(e instanceof FileNotFoundException) {
l--;
System.err.println(e);
} else {
System.err.println(e);
}
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Now I get an IOException right from the start (Stream closed). I tried incorporating the advice given by moving the InputStream out of the loop and implementing the code for correct data into the "try" branches.

You need to create only one InputStream and call the readObject() inside a while loop.

Related

Importing multiple objects with ObjectInputStream

After implementing the suggestions I was given on my last post, I now have a working piece of code without any error messages, but my code will still only print the first object from my file. I would be grateful for any suggestions.
import java.io.*;
import java.util.*;
public class Mainclass {
public static void main(String[] args) {
InputStream is;
try {
is = new FileInputStream("or.rtf");
ObjectInputStream ois;
try {
int l = 1;
ois = new ObjectInputStream(is);
while (l > 0) {
try {
Stone p = (Stone) ois.readObject();
System.out.println(p);
} catch(Exception e) {
if(e instanceof EOFException) {
l--;
System.err.println();
} else if(e instanceof FileNotFoundException) {
l--;
System.err.println(e);
} else {
System.err.println(e);
}
}
}
ois.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Code to save objects to a file:
import java.io.*;
import java.util.*;
public class Saver {
public static void main(String[] args) {
ArrayList<Stone> objects = new ArrayList<Stone>();
objects.add(new Stone("Max",50,90));
objects.add(new Stone("Fiona",30,60));
objects.add(new Stone("Sam",20,30));
for (int i = 0; i < objects.size(); i++ ) {
try {
OutputStream os = new FileOutputStream("qt.rtf");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(objects.get(i));
System.out.println(i);
oos.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
}
I implemented the println(i) to check whether the code was even executed in a loop.
Change the scope of ObjectOutputStream and FileOutputStream.
public static void main(String[] args) {
ArrayList<Stone> objects = new ArrayList<Stone>();
objects.add(new Stone("Max",50,90));
objects.add(new Stone("Fiona",30,60));
objects.add(new Stone("Sam",20,30));
try {
OutputStream os = new FileOutputStream("qt.rtf");
ObjectOutputStream oos = new ObjectOutputStream(os);
for (int i = 0; i < objects.size(); i++ ) {
oos.writeObject(objects.get(i));
System.out.println(i);
}
oos.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
You are also not reading from the same file you created or.rtf and qr.rtf.

Java InputStream with different Object Classes

my code has to read in two different Object Types (Bestellung, AKunde) through a ObjectOutputStream and save it in a csv file, which works.
But when i try to read them from the file it doesn't work.
Here is the code:
OutputStream:
LinkedList<Bestellung> bestellListe = verwaltungBestell.getBestellListe();
try {
fileOutputStream = new FileOutputStream(file);
outputStream = new ObjectOutputStream(fileOutputStream);
for (AKunde kunde : kundenliste) {
outputStream.writeObject(kunde);
}
for (Bestellung bestellung : bestellListe) {
outputStream.writeObject(bestellung);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
InputStream:
ArrayList<AKunde> kundenImport = new ArrayList<AKunde>();
ArrayList<Bestellung> bestellungenImport = new ArrayList<Bestellung>();
boolean cont = true;
try {
ObjectInputStream objectStream = new ObjectInputStream(new FileInputStream(directorie));
while (cont) {
AKunde kunde = null;
try {
kunde = (AKunde) objectStream.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (kunde != null) {
kundenImport.add(kunde);
} else {
cont = false;
}
}
while (cont) {
Bestellung bestellung = null;
try {
bestellung = (Bestellung) objectStream.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (bestellung != null) {
bestellungenImport.add(bestellung);
} else {
cont = false;
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
}
But it won't read the "Bestellungen" and won't save them into "bestellungenImport".
Anyone has a solution???
Your code never reaches the Bestellung reader part.
You have a false assumption that kunde =(AKunde)objectStream.readObject(); returns null.
Instead, it throws exception.
Oneway you can do is cast it like #luk2302.
Another way is to add a object count when writing your object stream:
outputStream.writeInt(kundenliste.size());
for (AKunde kunde : kundenliste) {
outputStream.writeObject(kunde);
}
outputStream.writeInt(bestellListe.size());
for (Bestellung bestellung : bestellListe) {
outputStream.writeObject(bestellung);
}
Then replace your while(cont) loop with a for each loop:
int kundeCount = objectStream.readInt();
for (int i = 0; i < kundeCount; i++) {
// Read and import kunde
}
You need to change your logic for reading objects. There are two main issues:
you never reset cont so the second while loop will never do anything
even if you did that you would always skip the first Bestellung since it was already read when the second loop is reached
I would propose something along the lines of:
Object object = objectStream.readObject();
if (object instanceof AKunde) {
kundenImport.add((AKunde) object);
} else if (object instanceof Bestellung) {
bestellungenImport.add((Bestellung) object);
} else {
// something else was read
}
You simply need to loop over this code and add proper error handling where needed.
I would suggest, you change the way you write your objects to ObjectOutputStream in the first place:
Directly write the kundenListe and bestellListe objects, so you dont't have to worry about types or number of elements when reading the objects again. Your stream of object then always contains two objects, the two lists.
// use try-with-resources if you're on Java 7 or newer
try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file))) {
// write the complete list of objects
outputStream.writeObject(kundenliste);
outputStream.writeObject(bestellListe);
} catch (IOException e) {
e.printStackTrace(); //TODO proper exception handling
}
Then you could read it just like that:
ArrayList<AKunde> kundenImport = new ArrayList<>();
ArrayList<Bestellung> bestellungenImport = new ArrayList<>();
//again try-with-resources
try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file))) {
kundenImport.addAll((List) inputStream.readObject());
bestellungenImport.addAll((List) inputStream.readObject());
} catch (IOException | ClassNotFoundException e) { //multi-catch, if Java 7 or newer
e.printStackTrace(); //TODO proper exception handling
}
Further reads:
The try-with-resources Statement
Catching Multiple Exception Types (...)

Client-Server, Object Input/Output, DeadLock

I am pretty new to writing client/server based apps. both server and client classes are kicked off in threads. New to using Object Output/input streams over tcp aswell. Have never had fun with serialization. In my application I am trying to use Object Input/Output Streaming but it looks like opening them is causing my application dies. The funny thing is that if I comment two lines:
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
Connection works nicely and app proceeds to the next panels etc. But I am still not capable of sending any objects throughout the socket. When I literally try to open those streams. It still connects but app get freezed. I 've got two questions:
first: is it better to use serialization
second: if I can use Object streaming, how should I open them? Can I do it inside the server/client thread?
Thanks for Your time
Here is the code of ClientApp:
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
Do you use Serializable interface for the Map object ?
If you still frozen at a step, its maybe because you try to read object (from server or client) and you didn't send it by the other side. While the object is not read it will wait for content.
I dont know how work your server, but you read response twice when oppenentReady is false.
if (inStream.readObject() != null) {
if (inStream.readObject() instanceof Boolean) {
//...
}
}
If this is not the expected behavior, you should store it in local variable.
Once again, this's smt I want to implement(in steps)
1. user choose to open connection(he becomes a server and waits for a client
to connect) - done.
2. second user choose to connect(becomes a client and connects to the
second player(server) - done.
3. Both get message that the connection is established and they are moved
to the next Panel where they do specific operations - done.
4.When anyone of them finishes, I want to tell it to the second guy
(it is represented by a boolean local varable) - here comes the problem.
5. When both have finished, they should be moved to the next Panel where
they play.(before they start playing, Maps that they have set in the previous Panel
should be sent to each other.
Next steps I can handle if Only I knew maybe not how to send those informations
but where to place sending code because it seems to be in the wrong place. Here is the full code of client/server classes:
connecting - is set to true in the other class after pushing the button.
iAmready - is set to true when player finishes setting up the map and should be sent to opponent,
because it triggers a specific operation by setting opponentIsReady to true when obtained.
public class ClientApp implements Runnable
{
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
FileOutputStream out = new FileOutputStream("/tmp/message.ser");
outStream = new ObjectOutputStream(out);
FileInputStream in = new FileInputStream("/tmp/message.ser");
inStream = new ObjectInputStream(in);
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}
inStream.close();
outStream.close();
in.close();
out.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public class ServerApp implements Runnable
{
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
public ServerApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e) {}
try
{
if (connecting)
{
hostServer = new ServerSocket(port);
socket = hostServer.accept();
connected = true;
connecting = false;
JOptionPane.showMessageDialog(null, "Connection Established!");
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
connected = connecting = false;
}
catch (IOException e)
{
connected = connecting = false;
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected(server)");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
inStream = new ObjectInputStream(socket.getInputStream());
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do servera!");
outStream = new ObjectOutputStream(socket.getOutputStream());
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
As i said before, you can not use readObject() more than once for the same object.
Example,
Use:
Object objectRead=inStream.readObject();
if (objectRead != null) {
if (objectRead instanceof Boolean) {
opponentIsReady = Boolean.valueOf(objectRead);
System.out.println(opponentIsReady);
} else if (objectRead instanceof Map) {
mapToGet = (Map) objectRead;
}
}
Instead of:
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
I think you didn't understand how it works:
When the client/server connection is etablished you can use Threads to read or write objects.
I give you code that you can test to understand how it works:
ServerApp:
public class ServerApp implements Runnable {
public static int port = 1000;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
private boolean connected = false;
public ServerApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
// Server initialization side
try {
hostServer = new ServerSocket(port);
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
// Accept will wait until a client try to connect
socket = hostServer.accept();
JOptionPane.showMessageDialog(null, "Connection Established!");
// Init streams when connection is etablished
inStream = new ObjectInputStream(socket.getInputStream());
outStream = new ObjectOutputStream(socket.getOutputStream());
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected = true;
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
int x = 0;
// The loop is made to send/receive all messages
while (connected) {
try {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
Object o = String.format("I send you a message (%s)", x++);
outStream.writeObject(o);
Object response = inStream.readObject();
System.out.println("Response: " + response);
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ClientApp:
public class ClientApp implements Runnable {
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = true;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
try {
// Client initialization side
socket = new Socket(hostIP, port);
// If the socket connection succeed it pass, else execption is thrown
JOptionPane.showMessageDialog(null, "Connection Established!");
// Initialize streams
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected=true;
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
}
// The loop will receive server message and send response
while (connected) {
try {
Object serverMessage = inStream.readObject();
System.out.println("Server sent: " + serverMessage);
Object myResponse = String.format("I received %s", serverMessage);
outStream.writeObject(myResponse);
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (connected) {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (connected) {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Deserialize multiple Java Objects

hello dear colleagues,
I have a Garden class in which I serialize and deserialize multiple Plant class objects. The serializing is working but the deserializing is not working if a want to assign it to calling variable in the mein static method.
public void searilizePlant(ArrayList<Plant> _plants) {
try {
FileOutputStream fileOut = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
for (int i = 0; i < _plants.size(); i++) {
out.writeObject(_plants.get(i));
}
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
deserializing code:
public ArrayList<Plant> desearilizePlant() {
ArrayList<Plant> plants = new ArrayList<Plant>();
Plant _plant = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
Object object = in.readObject();
// _plant = (Plant) object;
// TODO: ITERATE OVER THE WHOLE STREAM
while (object != null) {
plants.add((Plant) object);
object = in.readObject();
}
in.close();
} catch (IOException i) {
return null;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
return null;
}
return plants;
}
My invoking code:
ArrayList<Plant> plants = new ArrayList<Plant>();
plants.add(plant1);
Garden garden = new Garden();
garden.searilizePlant(plants);
// THIS IS THE PROBLEM HERE
ArrayList<Plant> dp = new ArrayList<Plant>();
dp = garden.desearilizePlant();
edit
I got a null Pointer exception
The solution of #NilsH is working fine, thanks!
How about serializing the entire list instead? There's no need to serialize each individual object in a list.
public void searilizePlant(ArrayList<Plant> _plants) {
try {
FileOutputStream fileOut = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(_plants);
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
public List<Plant> deserializePlant() {
List<Plants> plants = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
plants = in.readObject();
in.close();
}
catch(Exception e) {}
return plants;
}
If that does not solve your problem, please post more details about your error.
It may not always be feasible to deserialize a whole list of objects (e.g., due to memory issues). In that case try:
ObjectInputStream in = new ObjectInputStream(new FileInputStream(
filename));
while (true) {
try {
MyObject o = (MyObject) in.readObject();
// Do something with the object
} catch (EOFException e) {
break;
}
}
in.close();
Or using the Java SE 7 try-with-resources statement:
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(
filename))) {
while (true) {
MyObject o = (MyObject) in.readObject();
// Do something with the object
}
} catch (EOFException e) {
return;
}
If you serialize it to an array linear list, you can cast it back to an array linear list when deserializing it -- all other methods failed for me:
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
public class Program
{
public static void writeToFile(String fileName, Object obj, Boolean appendToFile) throws Exception
{
FileOutputStream fs = null;
ObjectOutputStream os = null;
try
{
fs = new FileOutputStream(fileName);
os = new ObjectOutputStream(fs);
//ObjectOutputStream.writeObject(object) inherently writes binary
os.writeObject(obj); //this does not use .toString() & if you did, the read in would fail
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
os.close();
fs.close();
}
catch(Exception e)
{
//if this fails, it's probably open, so just do nothing
}
}
}
#SuppressWarnings("unchecked")
public static ArrayList<Person> readFromFile(String fileName)
{
FileInputStream fi = null;
ObjectInputStream os = null;
ArrayList<Person> peopleList = null;
try
{
fi = new FileInputStream(fileName);
os = new ObjectInputStream(fi);
peopleList = ((ArrayList<Person>)os.readObject());
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch(EOFException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
os.close();
fi.close();
}
catch(Exception e)
{
//if this fails, it's probably open, so just do nothing
}
}
return peopleList;
}
public static void main(String[] args)
{
Person[] people = { new Person(1, 39, "Coleson"), new Person(2, 37, "May") };
ArrayList<Person> peopleList = new ArrayList<Person>(Arrays.asList(people));
System.out.println("Trying to write serializable object array: ");
for(Person p : people)
{
System.out.println(p);
}
System.out.println(" to binary file");
try
{
//writeToFile("output.bin", people, false); //serializes to file either way
writeToFile("output.bin", peopleList, false); //but only successfully read back in using single cast
} // peopleList = (ArrayList<Person>)os.readObject();
// Person[] people = (Person[])os.readObject(); did not work
// trying to read one at a time did not work either (not even the 1st object)
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("\r\n");
System.out.println("Trying to read object from file. ");
ArrayList<Person> foundPeople = null;
try
{
foundPeople = readFromFile("input.bin");
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (foundPeople == null)
{
System.out.println("got null, hummm...");
}
else
{
System.out.println("found: ");
for(int i = 0; i < foundPeople.size(); i++)
{
System.out.println(foundPeople.get(i));
}
//System.out.println(foundPeople); //implicitly calls .toString()
}
}
}

ObjectOutputStream, ObjectInputStream, and headers [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to understand object serialization better, so I am practicing with some code I got from my textbook. (My textbook doesn't explain how to read and write/append objects to a serialization file every time the program starts, which is what I need to do.) I took their program, which just overwrites existing data in a file with the objects from the current session, and add code to it so that it will append the objects and read the whole file instead. I found something really useful here: Appending to an ObjectOutputStream but even if I create a subclass of ObjectOutputStream, override the writeStreamHeader method, and call this subclass if the file already exists, which is what they did, it still throws a CorruptedStreamException. My guess is that I would need to set the pointer back to the beginning of the file, but that doesn't seem to be necessary as there is only one ObjectOutputStream. So, my question is, what else could I possibly need to do?
EDIT: Here is some code.
WriteData.java
import java.io.*;
import java.util.Scanner;
public class WriteData
{
private int number;
private String name;
private float money;
private ObjectInputStream testopen;
private ObjectOutputStream output; //This is for the output. Make sure that
//this object gets an instance of FileOutputStream so that it can write objects
//to a FILE.
private AppendObjectOutputStream appendobjects;
static Scanner input = new Scanner(System.in);
static DataClass d;
public void openfile()
{
//Try opening a file (it must have the ".ser" extension).
try
{
//output = new ObjectOutputStream(new FileOutputStream("test.ser"));
testopen = new ObjectInputStream(new FileInputStream("test.ser"));
}
//If there is a failure, throw the necessary error.
catch (IOException exception)
{
try
{
output = new ObjectOutputStream(new FileOutputStream("test.ser"));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} //end case createfile
if (testopen != null)
{
try
{
testopen.close();
appendobjects = new AppendObjectOutputStream(
new FileOutputStream("test.ser"));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void writedata()
{
//write the data until the user enters a sentry value.
System.out.println("Enter CTRL + z to stop input.\n");
System.out.print ("Enter the data in the following format: " +
"account_number name balance\n->");
while (input.hasNext())
{
System.out.print ("Enter the data in the following format: " +
"account_number name balance\n->");
try
{
number = input.nextInt();
name = input.next();
money = input.nextFloat();
//Make object with that data
d = new DataClass(number, name, money);
//write it to the file
if (output != null)
{
output.writeObject(d);
}
else if (appendobjects != null)
{
appendobjects.writeObject(d);
}
}
catch (IOException e)
{
System.out.println("Error writing to file.");
return;
}
}
System.out.println("\n");
} //end writedata
public void closefile()
{
try
{
if (output != null)
{
output.close();
}
else if (appendobjects != null)
{
appendobjects.close();
}
}
catch (IOException e)
{
System.out.println("Error closing file. Take precautions");
System.exit(1);
}
}
}
DataClass.java
import java.io.Serializable;
public class DataClass implements Serializable
{
private int someint;
private String somestring;
private float somefloat;
public DataClass(int number, String name, float amount)
{
setint(number);
setstring(name);
setfloat(amount);
}
public void setint(int i)
{
this.someint = i;
}
public int getint()
{
return someint;
}
public void setstring(String s)
{
this.somestring = s;
}
public String getstring()
{
return somestring;
}
public void setfloat(float d)
{
this.somefloat = d;
}
public float getfloat()
{
return somefloat;
}
}
AppendObjectOutputStream.java
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
public class AppendObjectOutputStream extends ObjectOutputStream
{
public AppendObjectOutputStream(FileOutputStream arg0) throws IOException
{
super(arg0);
// TODO Auto-generated constructor stub
}
//This is a function that is default in ObjectOutputStream. It just writes the
//header to the file, by default. Here, we are just going to reset the
//ObjectOutputStream
#Override
public void writeStreamHeader() throws IOException
{
reset();
}
}
ReadData.java
import java.io.*;
import java.util.Scanner;
public class ReadData
{
private FileInputStream f;
private ObjectInputStream input; //We should the constructor for this
//object an object of FileInputStream
private Scanner lines;
public void openfile()
{
try
{
f = new FileInputStream("test.ser");
input = new ObjectInputStream (f);
//input.reset();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
public void readdata()
{
DataClass d;
System.out.printf("%-15s%-12s%10s\n", "Account Number", "First Name",
"Balance");
try
{
while (true)
{
d = (DataClass)input.readObject(); //define d
//read data in from d
System.out.printf("%-15d%-12s%10.2f\n", d.getint(), d.getstring(),
d.getfloat());
}
}
catch (EOFException eof)
{
return;
}
catch (ClassNotFoundException e)
{
System.err.println("Unable to create object");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void closefile()
{
try
{
if (input != null)
{
input.close();
}
}
catch (IOException ex)
{
System.err.println("Error closing file.");
System.exit(1);
}
}
}
SerializationTest.java
public class SerializationTest
{
public static void main(String[] args)
{
ReadData r = new ReadData();
WriteData w = new WriteData();
w.openfile();
w.writedata();
w.closefile();
r.openfile();
r.readdata();
r.closefile();
}
}
I suggest to do it this way
ObjectOutputStream o1 = new ObjectOutputStream(new FileOutputStream("1"));
... write objects
o1.close();
ObjectOutputStream o2 = new AppendingObjectOutputStream(new FileOutputStream("1", true));
... append objects
o2.close();
it definitely works.
import EJP;
import Evgeniy_Dorofeev;
public class answer
{
private String answera, answerb;
public answer(String a, String b)
{
answera = a;
answerb = b;
}
public void main(String[] args)
{
answer(EJP.response(), Evgeniy_Dorofeev.response());
System.out.println(answera + '\n' + answerb);
}
}
You need to add a 'true' for the append parameter of new FileOutputStream() in the case where you are appending. Otherwise you aren't. Appending, that is.

Categories

Resources