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()
}
}
}
Related
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.
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 (...)
I am working on my first server project for school and I am receiving a NoSuchElementException when reaching the code below in my client. From my understanding, the way I have written it, the scanner should be waiting for the server to send back a string. Instead it seems to be jumping right to the exception. In the server code (second below) I have the output that is supposed to return all strings in an array. My goal is to have the client print all of the strings in the text area (status).
static void runClient() {
Socket client = null;
PrintWriter output = null;
Scanner input = null;
try {
client = new Socket("localhost", 5007);
input = new Scanner(client.getInputStream());
output = new PrintWriter(client.getOutputStream());
output.println(game);
output.println(numberOfPicks);
output.flush();
pStr("Data Sent");
while (true) {
pStr("Waiting for Server");
status.appendText(input.nextLine());
if (!input.hasNext())
break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (Exception e) {
}
try {
output.close();
} catch (Exception e) {
}
try {
client.close();
} catch (Exception e) {
}
}
}
private static void pStr(String string) {
System.out.println(string);
}
}
PARTIAL SERVER CODE BELOW
public void run() {
PrintWriter output = null;
Scanner input = null;
try {
// Get input and output streams.]
input = new Scanner(connection.getInputStream());
output = new PrintWriter(connection.getOutputStream());
String game;
int quickPicks;
try {
game = input.nextLine();
quickPicks = Integer.parseInt(input.nextLine());
switch (game) {
case "PowerBall":
ansStr = new pickNumbers(game, quickPicks, 69, 26).getQuickPicks();
break;
case "MegaMillions":
ansStr = new pickNumbers(game, quickPicks, 70, 25).getQuickPicks();
break;
case "Lucky4Life":
ansStr = new pickNumbers(game, quickPicks, 48, 18).getQuickPicks();
break;
default:
throw new RuntimeException("Incorrect Game");
}
} catch (Exception e) {
output.println(e.getMessage());
}
for (int i = 0; i < ansStr.length; i++) {
output.println(ansStr[i]);
//output.flush();
}
} catch (Exception e) {
pStr(e.getMessage());
} finally {
try {
input.close();
} catch (Exception e) {
}
try {
output.close();
} catch (Exception e) {
}
try {
connection.close();
} catch (Exception e) {
}
}
}
}
How about nesting status.appendText(input.nextLine()); in a test for hasNextLine e.g:
if(input.hasNextLine()){
status.appendText(input.nextLine());
}
I really don't know what to look for and if this is even possible. I am trying to code a dynamic Fileloader.
This is the code:
public static Serializable loadSerializable(Context context,
String filename, Object object) {
final String DEBUGTAG = "Loading data" ;
Serializable serializable = null;
ObjectInputStream oin = null;
try {
File file = new File(context.getFilesDir(), filename);
FileInputStream in = new FileInputStream(file);
oin = new ObjectInputStream(in);
Object readElement = oin.readObject();
serializable = (Serializable) readElement; // here I want dynamic casting
Log.d(DEBUGTAG, "Success : " + filename);
} catch (FileNotFoundException e) {
Log.d(DEBUGTAG, "File not found");
} catch (StreamCorruptedException e) {
Log.d(DEBUGTAG, "Stream Corrupted");
} catch (IOException e) {
Log.d(DEBUGTAG, "IOException");
} catch (ClassNotFoundException e) {
Log.d(DEBUGTAG, "Class not Found");
} catch (NullPointerException e) {
Log.d(DEBUGTAG, "NullPointer - File does not exist yet");
} finally {
if (oin != null)
try {
oin.close();
} catch (IOException e) {
Log.d(DEBUGTAG, "IOException - Stream not closed");
}
}
return serializable;
}
What I want to do now is instead of creating a new method for every single object I want to use the 3rd argument (object or whatever) for the type casting.
So I could write
String myString = loadSerializable(this, test.dat, String) or
ArrayList<Fragment> = loadSerializable(this, test.dat, ArrayList<Fragment>) and so on....
Help appreciated
Something like
public static <T> T loadSerializable(Context context, String filename) {
// ...
T t = (T) readElement;
// ...
return t;
}
I'm learning now how to do serialization using Java Language. I have read some posts and docs about the subject and I tried to do a simple example (below)
public class SterializeObject implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private transient int code;
public SterializeObject (String n, int c){
name = n;
code = c;
}
public void printAtributes (){
System.out.println("name: " + name + "; code: " + code);
}
}
public class MainClass {
public static void main(String[] agrs) {
SterializeObject ob1 = new SterializeObject("ana", 1);
SterializeObject ob2 = new SterializeObject("rita", 2);
try {
FileOutputStream fileOut = new FileOutputStream("file.data");
ObjectOutputStream outObj = new ObjectOutputStream(fileOut);
outObj.writeObject(ob1);
outObj.writeObject(ob2);
outObj.close();
System.out.println("Objects were serialized!");
} catch (IOException e) {
e.printStackTrace();
}
ArrayList<SterializeObject> list = new ArrayList<SterializeObject>();
try {
FileInputStream fileInput = new FileInputStream("file.data");
ObjectInputStream inputObj = new ObjectInputStream(fileInput);
Object o;
try {
while ((o = inputObj.readObject()) != null) {
list.add((SterializeObject) o);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Erro foi aqui! (1)");
}
inputObj.close();
fileInput.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Erro foi aqui! (2)");
}
for (int i = 0; i < list.size(); ++i) {
list.get(i).printAtributes();
}
}
}
I created a Class SterializeObject that implements java.io.Serializable with two variables: one string (name) and one int (code) that is transient. Then In the main I generate two instances of that class and I tried to write it in a file, that I have done successfully! After that, I try to read the two object with a Loop.. there is my problem.. since the ObjectInputStream dosen't have some kind of method to see if we are in the end or not. So, I tried to do with this condition: (o = inputObj.readObject()) != null.
My output is this:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at MainClass.main(MainClass.java:30)
Objects were serialized!
Erro foi aqui! (2)
name: ana; code: 0
name: rita; code: 0
I get the objects, but I get an error because, I think, is trying to access to something that doesn't exist.
Someone can tell me other way to do it?
Best Regards.
Read as many objects as the number of written objects, or write the list of objects itself, instead of writing every object one after the other.
(Or rely on the EOFException to detect the end of the stream, but this is ugly).
As many of you told me to do, I created a ArrayList and serialized the ArrayList.
My code is:
public class MainClass {
public static void main(String[] agrs) {
SterializeObject ob1 = new SterializeObject("ana", 1);
SterializeObject ob2 = new SterializeObject("rita", 2);
ArrayList <SterializeObject> list = new ArrayList<>();
list.add(ob1);
list.add(ob2);
ArrayList <SterializeObject> input = new ArrayList<SterializeObject>();
try {
FileOutputStream fileOut = new FileOutputStream("file.data");
ObjectOutputStream outObj = new ObjectOutputStream(fileOut);
outObj.writeObject(list);
outObj.close();
System.out.println("Objects were serialized!");
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fileInput = new FileInputStream("file.data");
ObjectInputStream inputObj = new ObjectInputStream(fileInput);
Object o;
try {
input = (ArrayList<SterializeObject>) inputObj.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Erro foi aqui! (1)");
}
inputObj.close();
fileInput.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Erro foi aqui! (2)");
}
for (int i = 0; i < input.size(); ++i) {
input.get(i).printAtributes();
}
}
}
And the output is:
Objects were serialized!
name: ana; code: 0
name: rita; code: 0
Thank you for the help!
Close the FileOutputStream also along with ObjectOutputStream
fileOut.close();
Why don't you add both object to an ArrayList, and serialize the ArrayList. Then you just have to Deserialize the ArrayList and it will be populated with both objects.
You can do this by placing the readObject call inside a try-catch block and catching that EOFException you get, signaling you have read all the objects.
Replace your while loop with this piece of code
do{
try
{
o = inputObj.readObject();
list.add((SterializeObject) o);
}
catch(EOFException e)
{
o = null;
}
}while (o != null);