This is my first experience with serialization. I have my data in an arraylist. When I deserialize it, the arraylist is empty and I can't figure out why. The arraylist contains only two objects (but in the future could hold more) of class Account. The Account class is serializable as I beleive is the case with ArrayList objects. Here is my code:
public class BankDatabase implements Serializable
{
public ArrayList<Account> accounts;
private static ObjectOutputStream output;
private static ObjectInputStream input;
public BankDatabase()
{
accounts = new ArrayList();
File database = new File("database.ser");
if(!database.exists())
{
Account testAccount[] = new Account[2];
testAccount[0] = new Account(12345, 54321, 1000.0, 1200.0);
testAccount[1] = new Account(98765, 56789, 200.0, 200.0);
accounts.add(0, testAccount[0]);
accounts.add(1, testAccount[1]);
}
else
loadDatabase();
}
public static void openIn()
{
try
{
input = new ObjectInputStream(Files.newInputStream(Paths.get("database.ser")));
}
catch (IOException ioException)
{
System.err.println("Could not open file. Closing Program.");
System.exit(1);
}
}
public static void openOut()
{
try
{
output = new ObjectOutputStream(Files.newOutputStream(Paths.get("database.ser")));
}
catch (IOException ioException)
{
System.err.println("Could not open file. Closing Program.");
System.exit(1);
}
}
public void readData()
{
try
{
while(true)
{
accounts.add((Account) input.readObject());
}
}
catch (EOFException endOfFileException)
{
System.out.printf("No More Records%n");
}
catch (ClassNotFoundException classNotFoundException)
{
System.err.println("Invalid object type.");
}
catch (IOException ioException)
{
System.err.println("Could not read file.");
}
}
public void saveData()
{
try
{
for(Account currentAccount : accounts)
{
output.writeObject(currentAccount);
}
}
catch (IOException ioException)
{
System.err.println("Error writing to file. Terminating");
}
}
public void closeOut()
{
try
{
if (output != null)
output.close();
}
catch (IOException ioException)
{
System.err.println("Error closing file. Terminating.");
System.exit(1);
}
}
public void closeIn()
{
try
{
if (input != null)
input.close();
}
catch (IOException ioException)
{
System.err.println("Error closing file. Terminating.");
System.exit(1);
}
}
public void loadDatabase()
{
openIn();
readData();
closeIn();
}
public void updateDatabase()
{
openOut();
saveData();
closeOut();
}
}
public class Account implements Serializable
{
public int accountNumber;
public int pin;
public double availableBalance;
public double totalBalance;
public Account(int theAccountNumber, int thePIN,
double theAvailableBalance, double theTotalBalance)
{
accountNumber = theAccountNumber;
pin = thePIN;
availableBalance = theAvailableBalance;
totalBalance = theTotalBalance;
}
ArrayList is Serializable, do objectOuput.writeObject(list) to save it and List list = (List)objectInputStream.readObject() to read back
Related
I'm trying to write couple of object using ObjectOutputStream to a file. After that, I read the file with ObjectInputStream. The problem is, I can only read first object in the file. When I opened the file with notepad++, I can see the entries for other objects.
Here writer part
public class FileProcess {
private ObjectOutputStream output;
private Accounts account;
public FileProcess() {}
public void WriteObject(Accounts account) {
this.account = account;
openFile();
addRecords();
closeFile();
}
private void openFile() {
try {
output = new ObjectOutputStream(Files.newOutputStream(Paths.get("record_files.txt"),CREATE,APPEND));
}catch (Exception e) {
System.out.println("\nError opening file");
}
}
private void addRecords() {
try {
output.writeObject(account);
}
catch (Exception e) {
System.out.printf("Error writing file %s",e);
}
}
private void closeFile() {
try {
if(output != null)
output.close();
} catch (Exception e) {
System.out.println("\nError closing file");
}
}
}
And Reader part
abstract class User {
private String userID;
private int password;
private String position;
private ObjectInputStream input;
public User(String userID, int password, String position) {
this.userID = userID;
this.password = password;
this.position = position;
}
boolean signIn() {
boolean found_check = false;
openFile();
found_check = checkRecords();
closeFile();
return found_check;
}
private void closeFile() {
try {
if(input != null)
input.close();
} catch (Exception e) {
System.out.println("Error closing file");
}
}
private boolean checkRecords() {
try {
while(true) {
Accounts account = (Accounts) input.readObject();
System.out.printf("%s %d %s",account.getUserID(),account.getPassword(),account.getPosition());
}
}
catch (Exception e) {
System.out.println("\nError reading file");
return false;
}
return false;
}
private void openFile() {
try {
input = new ObjectInputStream(Files.newInputStream(Paths.get("record_files.txt")));
}catch (Exception e) {
System.out.println("Error opening file");
}
}
}
Accounts class implements Serializable
public class Accounts implements Serializable {
private String userID;
private int password;
private String position;
public Accounts(String userID, int password, String position) {
try {
this.userID = userID;
this.password = password;
this.position = position;
}
catch (Exception e) {
System.out.printf(e.toString());
}
}
}
Your code is throwing the following exception: java.io.StreamCorruptedException: invalid type code: AC.
There's a good question and answer here
This was discovered by adding e.printStackTrace(); to the exception handler in User.checkRecords.
On my serialized XML File is only one attribute of my Object saved, although four should be saved. I think this is due to y XStream Object registering only one converter, although he should register four.
My Converters are all functioning individually. I tested them one by one.
My XML File:
<object-stream>
<model.Product>13</model.Product>
</object-stream>
My Product class which should be saved:
public class Product implements Externalizable, Serializable {
private static final long serialVersionUID = -8437751114305532162L;
#XStreamConverter(converter.NameConverter.class)
private SimpleStringProperty name;
#XStreamConverter(converter.PriceConverter.class)
private SimpleDoubleProperty price;
#XStreamConverter(converter.CountConverter.class)
private SimpleIntegerProperty quantity;
#XStreamConverter(converter.IDConverter.class)
private long id;
public Product(String name, int quantity, double price, long id)
{
this.name=new SimpleStringProperty(name);
this.quantity=new SimpleIntegerProperty(quantity);
this.price=new SimpleDoubleProperty(price);
this.id=id;
//Getter and Setter and implentation of Externalizable
My XStream class
XStream xstream;
ObjectInputStream ois;
ObjectOutputStream oos;
#Override
public void close() throws IOException {
if (oos != null) {
oos.close();
}
if (ois != null) {
ois.close();
}
}
#Override
public void writeObject(Product obj) throws IOException {
try {
oos.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
public void open(InputStream input, OutputStream output) throws IOException {
xstream = createXStream(model.Product.class);
converter.ConverterManager con=new ConverterManager();
con.registerAllConverters(xstream);
if (input != null) {
if (input.available() > 0) {
ois = xstream.createObjectInputStream(input);
}
}
if (output != null) {
oos = xstream.createObjectOutputStream(output);
}
}
}
My ConverterManager:
import com.thoughtworks.xstream.XStream;
public class ConverterManager {
public void registerAllConverters(XStream xstream)
{
xstream.aliasAttribute("Product Price", "price");
xstream.registerConverter(new PriceConverter());
xstream.aliasAttribute("Product ID", "id");
xstream.registerConverter(new IDConverter());
xstream.aliasAttribute("Product Name", "name");
xstream.registerConverter(new NameConverter());
xstream.aliasAttribute("Product quantity", "quantity");
xstream.registerConverter(new CountConverter());
}
}
My writeObject, open and close methods are called from this method from another class:
private void saveModel() {
XStreamStrategy s=new XStreamStrategy();
try {
s.open(getFilePath());
} catch (IOException e) {
e.printStackTrace();
}
for(fpt.com.Product p: model)
{
try {
s.writeObject(p);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
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();
}
}
}
}
}
I try to read data from file "sinhvien.dat" then push into array of Student.
My code:
private Student[] docFile() {
Student[] std = null;
FileInputStream f = null;
ObjectInputStream inStream = null;
try {
f = new FileInputStream("student.dat");
inStream = new ObjectInputStream(f);
std = (Student[]) inStream.readObject();// this line throw error
} catch (ClassNotFoundException e) {
System.out.println("Class not found");
} catch (IOException e) {
System.out.println("Error Read file");
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException ex) {
}
}
if (f != null) {
try {
f.close();
} catch (IOException ex) {
}
}
}
return std;
}
Class Student
public class Student implements Serializable { private String studName; Student(String name) { this.studName = name; } public Student() { } public String getStudName() { return studName; } public void setStudName(String studName) { this.studName = studName; } #Override public String toString() { return "Student Name :" + studName; } }
I don't know how to fix this error.
sorry for bad english :(
Exception in thread "Thread-3" java.lang.ClassCastException: btvn_l5.Student cannot be cast to [Lbtvn_l5.Student;
This means, that you cannot cast a single Student-obect into an array of Student-objects.
I think you serialize a Student and try to deserialize a Student[]. Th prefix [L indicates an array.
Take a look at you serializer.
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.