I'm execising with Object I/O and have made a very simple class(Thing) which only has one attribute(int weight)
I am getting a notSerializable exception and I really don't get it.
The Thing Class:
import java.io.Serializable;
public class Thing implements Comparable<Thing>, Serializable{
private static final long serialVersionUID = 1L;
private int weight;
public Thing(int weight) {
this.weight = weight;
}
public Thing(){
this((int)(Math.random()*1000));
}
public int getWeight() {
return weight;
}
#Override
public int compareTo(Thing o) {
return this.weight - o.weight;
}
}
My Saver class:
public class Saver {
private FileOutputStream fos;
private ObjectOutputStream oos;
private File file;
public Saver() {
file = new File("src/dataSaverReader/things.data");
}
public void saveArrayToFile(Thing[] array) {
try {
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (Thing element : array) {
try {
oos.writeObject(element);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Exception Details:
java.io.NotSerializableException: methods.Thing
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at dataSaverReader.Saver.saveArrayToFile(Saver.java:32)
at methods.Root.go(Root.java:48)
at methods.Root.main(Root.java:17)
Related
I am making an Email Client(for class) and i want to store the messages i send everyday in a single file.I am going to use serialization for this.I tried appending to a file by setting append to true in FileOutputStream.Below is the code i wrote.But it throws a StreamCorruptedException(stack trace given below).I cannot seem to find the reason why.I would like to know whether there is a better way to store multiple objects to a single file using serialization.Any help is appreciated.Thanks in advance.
//For reading and writing objects to files
interface MyFileHandler<T> {
public void write(T input );
public ArrayList<T> read();
}
class FileHandlerObject implements MyFileHandler<EmailMessage>
{
public void write(EmailMessage input){
try{
FileOutputStream fileOutputStream = new FileOutputStream("emails.ser",true);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(input);
objectOutputStream.flush();
objectOutputStream.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public ArrayList<EmailMessage> read(){
ArrayList<EmailMessage> messages=new ArrayList<EmailMessage>();
try{
FileInputStream fileInputStream=new FileInputStream("emails.ser");
ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
boolean cont = true;
while (cont) {
if(fileInputStream.available()!=0)
{
Object obj=objectInputStream.readObject();
EmailMessage message=(EmailMessage)obj;
messages.add(message);
}
else{
cont=false;
}
}
objectInputStream.close();
return messages;
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException c)
{
c.printStackTrace();
}
catch(ClassCastException c)
{
c.printStackTrace();
}
return null;
}
public static void main(String[] args) {
FileHandlerObject f=new FileHandlerObject();
ArrayList<EmailMessage> a=f.read();
a=f.read();
}
}
And the Email Message class that i serialize
public class EmailMessage implements Serializable{//implement serializables
private String recipient;
private String subject;
private String content;
private String date;
public void setRecipient(String recipient)
{
this.recipient=recipient;
}
public String getRecipient()
{
return this.recipient;
}
public void setSubject(String subject){
this.subject=subject;
}
public void setContent(String content){
this.content=content;
}
public String getSubject(){
return this.subject;
}
public String getContent(){
return this.content;
}
public void setDate(String date)
{
this.date=date;
}
public String getDate()
{
return this.date;
}
public String printDetails()
{
String details="Recipient: "+getRecipient()+
"\nSubject: "+getSubject()+
"\nEmail content: "+getContent()+
"\nDate Sent: "+getDate();
return details;
}}
And below is the stack trace
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1723)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:508)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:466)
at FileHandlerObject.read(MyFileHandler.java:46)
at FileHandlerObject.main(MyFileHandler.java:89)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
How can i fix problem with load ArrayList from file?
Full code is on the git:
project github link
When I load data from file I'll get it back -> IOException
I'm learning to use the stream so I'm writing it to a file.
After the end of the program, I want to write the time the user has reached in the arraylist and list all the times with which the game was finished.
package sk.games.puzzle;
import java.io.*;
import java.util.*;
public class BestTimes implements Iterable<BestTimes.PlayerTime>, Serializable{
private static final String BESTTIME_DB = System.getProperty("user.home")
+ System.getProperty("file.separator")
+ "best.time";
private List<PlayerTime> playerTimes = new ArrayList<>();
public Iterator<PlayerTime> iterator() {
return playerTimes.iterator();
}
public void addTime(String name, int time){
playerTimes.add(new PlayerTime(name, time));
Collections.sort(playerTimes);
}
public void load(){
ObjectInputStream load = null;
try {
load = new ObjectInputStream(new FileInputStream(BESTTIME_DB));
playerTimes = (ArrayList<PlayerTime>) load.readObject();
} catch (FileNotFoundException e) {
System.err.println("fail nebola najdena db");
} catch (IOException e) {
System.err.println("fail nebola otvorena db");
} catch (ClassNotFoundException e) {
System.err.println("fail nebol najdeny zaznam");
} finally {
if (load != null) {
try {
load.close();
} catch (IOException e) {
//empty
}
}
}
}
public void save() {
ObjectOutputStream save = null;
try {
save = new ObjectOutputStream(new FileOutputStream(BESTTIME_DB));
save.writeObject(playerTimes);
} catch (FileNotFoundException e) {
System.err.println("fail db neexistuje");
} catch (IOException e) {
System.err.println("fail nepodarilo sa otvorit db");
} finally {
if (save != null) {
try {
save.close();
} catch (IOException e) {
//empty
}
}
}
}
#Override
public String toString() {
Formatter f = new Formatter();
for (int i = 0; i < playerTimes.size(); i++) {
PlayerTime pt = playerTimes.get(i);
f.format("%02d. %s - %ds.\n", i, pt.getName(), pt.getTime());
}
return f.toString();
}
public static class PlayerTime implements Comparable<PlayerTime> {
private final String name;
private final int time;
public PlayerTime(String name, int time) {
this.name = name;
this.time = time;
}
public String getName() {
return name;
}
public int getTime() {
return time;
}
#Override
public int compareTo(PlayerTime o){
return Integer.compare(this.time, o.getTime());
}
}
}
The problem is that your PlayerTime class is not serializable.
public static class PlayerTime implements Comparable<PlayerTime> { }
should be
public static class PlayerTime implements Comparable<PlayerTime> implements Serializable { }
It's not necessary to make BestTimes serializable unless you do write BestTimes object to file.
I have written a Netty.io system in which I can easily send text files back and forth, but now I do not only want to send text files at the byte level, but if I announce before that comes a jar, even send a jar file at byte level.
Now I have tried only to send them like a normal file where logically a corrupt jar comes out.
So I send the text files:
public void sendFile(Channel channel, File files, String path) {
new Thread(new Runnable() {
#Override
public void run() {
sendFileInfo(channel,files,path);
while (file.containsKey(files.getName())) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
FileInputStream fis = new FileInputStream(files);
byte[] bytes = new byte[512];
int i =0;
int length;
while((length =fis.read(bytes))>0){
PacketOutFile512Bytes bit = new PacketOutFile512Bytes(i,files.getName(),length,bytes);
channel.writeAndFlush(bit);
if(!cache.containsKey(files.getName()))
cache.put(files.getName(),new HashMap<>());
HashMap<Integer, Timer> timecache = cache.get(files.getName());
timecache.put(i,new Timer());
timecache.get(i++).schedule(new TimerTask() {
#Override
public void run() {
channel.writeAndFlush(bit);
}
},Main.getInstance().getTimeout()*1000,Main.getInstance().getTimeout()*1000);
Thread.sleep(100);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public void writeFile(Channel channel, String file, int length){
new Thread(new Runnable() {
#Override
public void run() {
File sending = new File(path.get(file),file);
try {
sending.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
for(int i =0; i< amountofPackets.get(file);i++)
fos.write(cache.get(file).get(i),0,length);
fos.close();
channel.writeAndFlush(new PacketOutFileSucess(file));
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
Now I am looking for a method how to copy a jar on level of bytes that I can send with the same package.
This is how the packet looks for the byte snippet:
import de.letsplaybar.fileserver.ValueSizeException;
import lombok.Getter;
public class PacketInFile512Bytes implements Packet {
private #Getter int packetId;
private #Getter String name;
private #Getter int length;
private #Getter byte[] value;
public PacketInFile512Bytes() {
value = new byte[512];
}
public PacketInFile512Bytes(int packetId, String name, int length, byte[] value) throws ValueSizeException {
if(value.length != 512)
throw new ValueSizeException();
this.packetId = packetId;
this.name = name;
this.length = length;
this.value = value;
}
#Override
public void read(PacketSerilizer serilizer) {
packetId = serilizer.readInt();
name = serilizer.readString();
length = serilizer.readInt();
for (int i = 0; i<512;i++)
value[i] = serilizer.readByte();
}
#Override
public void write(PacketSerilizer serilizer) {
serilizer.writeInt(packetId);
serilizer.writeString(name);
serilizer.writeInt(length);
serilizer.writeBytes(value);
}
}
Who knows a way how I can do that?
Ever thank you in advance.
Letsplaybar
This question already has answers here:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException
(2 answers)
Closed 6 years ago.
I am trying to read all objects from the file. Below is the snippet of the method use to fetch list of object from file.
public List displayParties() {
ObjectInputStream ois = null;
List<RegisterParty> results = new ArrayList();
try {
FileInputStream fis = new FileInputStream("/media/user/disk2/myapp/assignment/party.ser");
ois = new ObjectInputStream(fis);
while (true) {
System.out.println(" inside while true");
results.add((RegisterParty) ois.readObject());
System.out.println(results);
}
} catch (IOException ex) {
ex.printStackTrace();
}
catch (Exception ex){
ex.printStackTrace();
} finally{
try {
ois.close();
}catch (IOException ex){
ex.printStackTrace();
}
}
return results;
}
RegisterParty Class :
public class RegisterParty implements Serializable {
String bookingPersonName;
String childName;
String childAge;
String theme;
String foodAlergies;
String noOfGuest;
String specialGuest;
public String getBookingPersonName() {
return bookingPersonName;
}
public void setBookingPersonName(String bookingPersonName) {
this.bookingPersonName = bookingPersonName;
}
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
public String getChildAge() {
return childAge;
}
public void setChildAge(String childAge) {
this.childAge = childAge;
}
public String getTheme() {
return theme;
}
public void setTheme(String theme) {
this.theme = theme;
}
public String getFoodAlergies() {
return foodAlergies;
}
public void setFoodAlergies(String foodAlergies) {
this.foodAlergies = foodAlergies;
}
public String getNoOfGuest() {
return noOfGuest;
}
public void setNoOfGuest(String noOfGuest) {
this.noOfGuest = noOfGuest;
}
public String getSpecialGuest() {
return specialGuest;
}
public void setSpecialGuest(String specialGuest) {
this.specialGuest = specialGuest;
}
public String toString(){
return bookingPersonName+" "+childName+" "
+childAge+" "+foodAlergies+" "+theme+" "+noOfGuest+" "+specialGuest;
}
}
But getting the below exception :
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: models.RegisterParty
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1354)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at helper.HelperFunctions.displayParties(HelperFunctions.java:39)
at services.PartyOperations.listAllParties(PartyOperations.java:64)
at assignment.App.main(App.java:34)
at helper.HelperFunctions.saveParty(HelperFunctions.java:24)
at services.PartyOperations.registerParty(PartyOperations.java:53)
at assignment.App.main(App.java:28)
Caused by: java.io.NotSerializableException: models.RegisterParty
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at helper.HelperFunctions.saveParty(HelperFunctions.java:20)
at services.PartyOperations.registerParty(PartyOperations.java:52)
... 1 more
RegisterParty implements the serializable interface. Its a menu based app, so when i save the object in file, its save successfully. But call the method to get all object in list, its throw the exception. Any Idea why?
This method successfully execute to serialize the object:
public void saveParty(RegisterParty registerParty){
try {
FileOutputStream fout = new FileOutputStream("/media/user/disk2/myapp/assignment/party.txt");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(registerParty);
oos.close();
System.out.println("Successfull Register");
System.out.println("========Select you choice========");
App.main(str);
}
catch (Exception ex){
ex.printStackTrace();
}
}
When I implement a Serializable object I add a static variable serialVersionUID to the class:
private static final long serialVersionUID = -1892561327013038124L;
This line gets added as a suggestion by either the eclipse or android studio. I don't know how to do it with IntelliJIdea.
It worth a try! I believe this ID used for deserialisation.
There was conflict in fileToRead & fileToWrite.
FileInputStream fis = new FileInputStream("/media/user/disk2/myapp/assignment/party.ser");
FileOutputStream fout = new FileOutputStream("/media/user/disk2/myapp/assignment/party.txt");
When Im trying to read an object and store in arraylist but im getting an exception this is the part of code where im facing a problem.
public class Customer implements Serializable {
private String username;
private String password;
private int age;
private String accttype;
private String acctno;
private float amount;
Customer() {
System.out.println("Im in Customer");
}
public boolean writeToDataBase(String uname, String pwd, int cage, String caccttype, String cacctno, float camount) throws IOException {
Customer custobj = new Customer();
FileOutputStream fos=null;
ObjectOutputStream oos=null;
custobj.username = uname;
custobj.password = pwd;
custobj.age = cage;
custobj.accttype = caccttype;
custobj.acctno = cacctno;
custobj.amount = camount;
try {
fos=new FileOutputStream("Customerdetails.txt",true);
oos=new ObjectOutputStream(fos);
oos.writeObject(custobj);
oos.close();
fos.close();
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
finally
{
fos.close();
oos.close();
}
}
public boolean retriveFromDataBase(int a) throws IOException
{
try {
Customer custobj = new Customer();
FileInputStream fis=null;
ObjectInputStream ois=null;
ArrayList<Customer> custlist;
try {
custlist = new ArrayList<Customer>();
fis = new FileInputStream("Customerdetails.txt");
ois = new ObjectInputStream(fis);
while (fis.available()!=0) {
custobj=(Customer)ois.readObject();
custlist.add(custobj);
}
System.out.println("Customer List" + custlist.size());
if (a == 3) {
for (int i = 0; i < custlist.size(); i++) {
custobj = custlist.get(i);
custobj.displayCustomers();
}
}
return true;
} catch (Exception ex) {
System.out.println(ex.toString());
System.out.println("No users are presnt in the file");
return false;
}
finally
{
ois.close();
fis.close();
}
}
catch(Exception ex)
{
System.out.println(ex.toString());
return false;
}
}
public void displayCustomers()
{
try
{
System.out.println("details"+username+"\t"+age+"\t"+password+"\t"+acctno+"\t"+accttype+"\t"+amount);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
Does your object implement the Serializiable or Externalizeable interface? If yes do you use non transitive objects that don't implement serializiable/externalizeable and don't offer a argumentless default constructor?
Without further information (which exception, more code) it's hard to say.
I noted that the program throws java.io.StreamCorruptedException, when you run it for the second time. It works fine when you run it only once.
The problem is that you cannot APPEND to the same file : Customerdetails.txt every time you serialize in writeToDatabase(..) method. So remove the append flag : "true" in the call to constructor of FileOutputStream in writeToDatabase(..) method.