I have three class as boat,car,truck etc who extend from vehicle , I write all the object of this in a file say vehicleOrder.dat like this :
fout = new FileOutputStream("VehicleOrders.dat");
oos = new ObjectOutputStream(fout);
oos.writeObject(v); //where v is object of boat,truck car etc
Till here its good ,it writes, but when I try to read the dat file like this,
fin = new FileInputStream("VehicleOrders.dat");
ois = new ObjectInputStream(fin);
vehicle readInstance=null;
do{
readInstance = (vehicle)ois.readObject();
if(readInstance != null)
{
orderList.add(readInstance);
}
}
while (readInstance != null);
it reads the two objects which are in the dat file but after that goes to the do again and gives null pointer exception
It seems like your class doesn't have 0-param-Constructor.
Maybe this link will help you out about the explanation
ObjectInputStream expects a visible no-arg constructor for the class instance you are trying to deserialize. I assume your class doesn't have one. Add one.
Related
Is there a semantic difference between the following two options? Is any one of them more secure than the other in terms of automatic resource management?
Option1:
try ( ObjectInputStream in = new ObjectInputStream(new
FileInputStream("fooFile")) ) {
...
}
Option2:
try (FileInputStream fin = new FileInputStream("fooFile");
ObjectInputStream in = new ObjectInputStream(fin)) {
...
}
See here: http://www.stackoverflow.com/a/21348893/1419315
The argument there is, essentially, that with the first variant, FileInputStream.close () will not get called when construction of the ObjectInputStream fails.
Actually, I searched the solution for that in web. I also found Copy an object in Java. In my object, there are a lot mapping.
Even I use Cloneable and Copy Constructor, I still need to copy for each fields?
My requirement is to know which data changed between Old Object and New Object.
My object Example Tree :
MotorProposal
- startDate : Date ---> can change
- endDate : Date ---> can change
- customer : Cutomer
- vehicleList : List<Vehicle> ---> can chnage
- carNo : String ---> can change
- loading : int ---> can change
- cubicCapacity : int ---> can chnage
- driver : Driver ---> can change
- fullName : String ---> can change
- address : Stirng ---> can change
- license : Stirng ---> can change
- expYear : int ---> can change
- model : Model
-there other fields
-there other fields
Is there another way to create new Instance with the same value without copying for each field?
My expected program
MotorProposal oldProposal = --> come from DB
MotorProposal newProposal = org.someapi.ObjectUtil.newInstance(oldProposal);
Update
Currently, I solve this case Martin Dinov suggested. As below.
ObjCopy.java
public class ObjCopy {
public static Serializable newInstance(Serializable obj) {
Serializable result = null;
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(buffer);
oos.writeObject(obj);
oos.flush();
oos.close();
ByteArrayInputStream in = new ByteArrayInputStream(buffer.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
return (Serializable)ois.readObject();
} catch (Exception e) {
//do nothing
e.printStackTrace();
}
return result;
}
}
Test.java
public class Test {
public static void main(String[] args) {
Country country = new Country();
country.setName("Myanmar");
Province province_1 = new Province();
province_1.setCountry(country);
province_1.setName("Yangon");
Province province_2 = (Province)ObjCopy.newInstance(province_1);
province_2.getCountry().setName("USA");
System.out.println(province_1.getName() + "-" + province_1.getCountry().getName());
System.out.println(province_2.getName() + "-" + province_2.getCountry().getName());
}
}
Output
Yangon-Myanmar
Yangon-USA
How about Yoni Roit's second proposal from the Stackoverflow link you provide? In other words, serialize and then deserialize the object - so this will result in deep copying your object byte-wise. You need to have your class implement Serializable. As long as all class fields can be serialized, this approach should work. However, serializing and deserializing objects can be quite slow apparently - probably not an issue if you want to do this out of convenience, rather than out of efficiency. Here's a simple example of re-creating a new ArrayList:
ArrayList<Integer> foo = new ArrayList<Integer>();
foo.add(5);
foo.add(3);
foo.add(1);
ArrayList<Integer> obj = null;
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(foo);
out.flush();
out.close();
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
bos.toByteArray()));
obj = (ArrayList<Integer>)in.readObject();
In your case, you'd want to type-cast to your specific class of course. This way you don't have to explicitly copy each field in the class.
No CyCDemo, there are a lot of issues about the Cloneable interface and the reason of and the reasons why Java has not implemented a deep copy.
In any case get an eye there:
https://code.google.com/p/cloning/
I'm trying to print objects into file.
Then I want to import them back to my program.
ObjectOutputStream not working, What am I missing? (try, catch not visible here but they're doing their job)
Map< Account, Customer> customerInfo = new HashMap< Account, Customer>();
File bankFile = new File("Bank.txt");
FileOutputStream fOut = new FileOutputStream( bankFile);
ObjectOutputStream objOut = new ObjectOutputStream(fOut);
for(Map.Entry<Account, Customer> e : bank.customerInfo.entrySet())
{
objOut.writeObject(e.getValue());
objOut.writeObject(e.getKey());
}
objOut.flush();
objOut.close();
fOut.close();
My problem here is that ObjectOutputStream is not working properly, it prints some weird code. I've used other methods to print out to file and they work just fine.
I've tried printing to different file extensions,
I tried changing the encoding for both the file and eclipse.
I tried different methods for getting the info from the Map using ObjectOutputStream. Is there a reason why ObjectOutputStream prints weird characters that I haven't think of? The entire file is almost impossible to read. Thanks!
Ps. some of the weird print, don't know if it helps.
¬ísrCustomerDìUðkJ
personalIdNumLnametLjava/lang/String;xpthellosr
SavingAccountUÞÀÀ;>ZfreeWithdrawDwithdrawalInterestRateLaccountTypeq~xrAccount é=UáÐI
accountNumberDbalanceDinterestRateLaccountTypeq~L transListtLjava/util/List;xpé?záG®{tsrjava.util.ArrayListxÒÇaIsizexpw
x?záG®{tSaving Accountq~sr
CreditAccountÝ
*5&VcLaccountTypeq~xq~ê?záG®{q~sq~ w
xtCredit Account
It's really quite simple. First things first, create a class that implements Serializable. Serializable is a marker interface, so you don't need to implement any methods for it:
public class Shoe implements Serializable { ... }
NOTE: If Shoe has other classes in it, for example Heel, or Buckle, those classes also need to implement the Serializable interface.
Next step is to write that to a file, using an ObjectOutputStream.
FileOutputStream out = new FileOutputStream("myfile.txt");
// Create the stream to the file you want to write too.
ObjectOutputStream objOut = new ObjectOutputStream(out);
// Use the FileOutputStream as the constructor argument for your object.
objOut.writeObject(new Shoe("Prada"));
// Write your object to the output stream.
objOut.close();
// MAKE SURE YOU CLOSE to avoid memory leaks, and make sure it actually writes.
There you have it. The serialized object is written to the txt file. Now to read it, it's just a case of using the ObjectInputStream.
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("myfile.txt");
Object obj = objIn.readObject();
if(obj instanceof Shoe)
{
Shoe shoe = (Shoe)obj;
}
And you've got an object you can use.
I'm completely new to programming, so I'm having a difficult time resolving my own errors. Someone advised me to try it on this website, so I thought why not give it a shot.
The other posts that I found regarding this error didn't seem very relevant: most were people advising to close the input stream, but my code already does that.
What I want it to do: Write a Photo object called "photo" to a file called "test.ser". Then read the file "test.ser" AND return the path of the object ("photo") in "test.ser" back to me.
What it actually does: Writes a Photo object called "photo" to "test.ser". Reads "test.ser", returns an EOFException and no path.
Returning the path isn't actually very important, as long as it returns something of value to me. But I am getting the same error when I use "System.out.println(photo)" or "photo.getId()".
I'm not very sure what I need to paste here, so I will post the two try/catch-es that I use for serializing and deserializing the object:
Serializing object:
File test = new File("path.../something.ser");
Photo photo = new Photo(2, "..\\images\\2.jpg", getImage("..\\images\\2.jpg"));
try {
FileOutputStream fos = new FileOutputStream(test);
ObjectOutputStream out = new ObjectOutputStream(fos);
if (!test.exists()) {
test.createNewFile();
}
out.writeObject(photo);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
Deserializing object:
try {
FileInputStream fis = new FileInputStream(test);
ObjectInputStream in = new ObjectInputStream(fis);
in.readObject();
photo = (Photo)in.readObject();
photo.getPath();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
And the error:
run:
null
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2571)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1315)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at view.Main.<init>(Main.java:103)
//103 is the line that casts the input object to a Photo object.
BUILD SUCCESSFUL (total time: 1 second)
From what I unstander the error occurs when I am trying to type cast the object - that I receive through the method readObject - to a "photo" class object. At least, that's what the error at line 103 is refering to.
I read elsewhere that the error means that I "tried to read more objects than there actually are there". Not sure what that means though, because I just want it to read 1 image - which should be within the object - and return its location.
Also I read that ObjectInputStream never returns null, unless I gave that value somewhere. But it actually is returning(?) "null", even though my code doesn't contain a null value...
I've been at it for days now (yes I am just that bad) and still no luck.
You read it twice:
in.readObject();
photo = (Photo)in.readObject();
Remove the first line.
Also you don't have to create the file. The output stream will do that for you.
Is it possible to ObjectOutputStream/ObjectInputStream an internal class? I can write it OK, and examine the created file, but when I try to read it back in using ObjectInputStream, I get an EOFException just trying to read an Object o = oos.readObject();
I use the same File object to open both streams, so that's not the problem.
It seems to be independant of the nature of the internal Class - a class with just a public int fails identically to a more complex class.
I have to move on, and create a regular class, and instantiate in the sender class, but I hate to walk away not knowing if it is possible, and if not why not.
Update: Related issues that were the cause of the problem:
A. You cannot re-open a file written with an ObjectOutputStream and append: a second header is written and corrupts the file.
B. Serializing a HashMap using ByteOutputStream to do a hash digest doesn't work, because when you read the HashMap back in from a ObjectOutputStream file, you may very well get a different byte[] from ByteOutputStream because of variations in pair order: the content is the same, but the byte[] (and so the hash disgest) is not.
Hope this helps someone save some time.
This one works for me. Please look for any differences to your solution.
public class Example implements Serializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
new Example().run();
}
private void run() throws IOException, ClassNotFoundException {
Inner inner = new Inner();
inner.x = 5;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream( out );
outputStream.writeObject( inner );
ByteArrayInputStream in = new ByteArrayInputStream( out.toByteArray() );
ObjectInputStream inputStream = new ObjectInputStream( in );
Inner inner2 = (Inner) inputStream.readObject();
System.out.println( inner2.x );
}
class Inner implements Serializable {
int x;
}
}
Can you include a small bit of sample code? The most obvious explanation is that you're not closing / flushing the output stream before you try to read it back in.