Writing a BufferedImage cache and save it to disk - java

I'm developing a java application in which I load some long lists containing images (downloaded from web), so I added a quick HashMap<String,BufferedImage> as a cache, to avoid redownloading the same image multiple times.
This works fine and the application is way faster, but it would be nice to let this cache persist through the various sessions, so I changed my cache to be serialized.
BufferedImage is not Serializable, so I had to wrote my custom methods.
My file structure should be something like:
(int) number of elements
[(URL) image's key
(Object) image written using ImageIO] n times
While file saving seems fine (at least I have no exceptions), when I try to load the URL it throws java.io.OptionalDataException with length = 4 and I don't understand why. The first iteration goes fine, but I have this exception as soon as I try to load the second URL, so I suspect that there's something wrong in the way I load the first image.
Here's the full code :
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class PicturesCache {
private static HashMap<String, BufferedImage> picturesCache;
private static final String cacheDiskLocation = "pictures_cache.map";
private static void writeCache(ObjectOutputStream oos, HashMap<String, BufferedImage> data) throws IOException {
// Number of saved elements
oos.writeInt(data.size());
// Let's write (url, image) for each entry in the cache
for (Entry<String, BufferedImage> entry : data.entrySet()) {
oos.writeObject(new URL(entry.getKey()));
ImageIO.write(entry.getValue(), "png", oos);
}
}
private static HashMap<String, BufferedImage> readCache(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// Number of saved elements
int size = ois.readInt();
// Cache
HashMap<String, BufferedImage> result = new HashMap<>(size);
// Let's read (url, image) and add them to cache
for (int i = 0; i < size; i++) {
String url = ((URL) ois.readObject()).toString(); // EXCEPTION HERE
BufferedImage image = ImageIO.read(ois);
result.put(url, image);
}
return result;
}
public static void loadCache() {
picturesCache = new HashMap<>();
File file = new File(cacheDiskLocation);
if (file.isFile()) {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
picturesCache = readCache(ois);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(PicturesCache.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
ois.close();
fis.close();
} catch (IOException ex) {
Logger.getLogger(PicturesCache.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
System.out.println("Cache loaded with " + picturesCache.size() + " elements");
}
public static void saveCache() {
File file = new File(cacheDiskLocation);
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
if (file.isFile()) {
file.delete();
}
file.createNewFile();
fos = new FileOutputStream(file);
oos = new ObjectOutputStream(fos);
writeCache(oos, picturesCache);
} catch (IOException ex) {
Logger.getLogger(PicturesCache.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
System.out.println("Cache saved with " + picturesCache.size() + " elements");
oos.close();
fos.close();
} catch (IOException ex) {
Logger.getLogger(PicturesCache.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static boolean contains(String url) {
return picturesCache.containsKey(url);
}
public static BufferedImage get(String url) {
return picturesCache.get(url);
}
public static void put(String url, BufferedImage image) {
picturesCache.put(url, image);
}
}

The error occurs because ImageIO.read(...) doesn't read all the data that was written using ImageIO.write(...). You can write the image to the ObjectOutputStread as a byte[]. For example:
private static void writeCache(ObjectOutputStream oos,
HashMap<String, BufferedImage> data) throws IOException {
// Number of saved elements
oos.writeInt(data.size());
// Let's write (url, image) for each entry in the cache
for (Entry<String, BufferedImage> entry : data.entrySet()) {
oos.writeObject(new URL(entry.getKey()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(entry.getValue(), "jpg", baos);
byte[] bytes = baos.toByteArray();
oos.writeObject(bytes);
}
}
private static HashMap<String, BufferedImage> readCache(
ObjectInputStream ois) throws IOException, ClassNotFoundException {
// Number of saved elements
int size = ois.readInt();
// Cache
HashMap<String, BufferedImage> result = new HashMap<>(size);
// Let's read (url, image) and add them to cache
for (int i = 0; i < size; i++) {
String url = ((URL) ois.readObject()).toString(); // EXCEPTION HERE
ByteArrayInputStream bais = new ByteArrayInputStream(
(byte[]) ois.readObject());
BufferedImage image = ImageIO.read(bais);
result.put(url, image);
}
return result;
}

Related

Serialization issue : de.ruedigermoeller

Trying to get https://github.com/RuedigerMoeller/fast-serialization framework as drop in replacement for my JVM serializer. As a first step.
Here is my serializer:
static FSTConfiguration conf = FSTConfiguration.createDefaultConfiguration();
public Serialiser() {
conf.registerClass(MapSerializableForm.class, // etc// ...
}
public byte[] serialise(Object obj) {
byte[] bytes = null;
try {
final ByteArrayOutputStream b = new ByteArrayOutputStream();
final FSTObjectOutput o = new FSTObjectOutput(b);
o.writeObject(obj);
bytes = b.toByteArray();
b.close();
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
public Object deserialize(byte[] bytes) {
Object deser = null;
try {
final ByteArrayInputStream b = new ByteArrayInputStream(bytes);
final FSTObjectInput o = new FSTObjectInput(b);
deser = o.readObject();
b.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return deser;
}
The class that is causing me problems is this one: I'm wrapping JavaFX images with Swing images to help me serialise them. My code does work with the standard Java serializer, but is v. slow. I'm hopeful for improvements, if I can get it working. The result is a nullpointerException during deserialization. It's late, here, but I've tried to be clear.
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
public class SerializableImage implements Serializable {
private static final long serialVersionUID = 7984341875952256208L;
public transient Image image ;
public SerializableImage(Image image) {
this.image=image;
}
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
BufferedImage bufferedImage = ImageIO.read(s); //image comes back null !
image = SwingFXUtils.toFXImage(bufferedImage, null);
}
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", s);
}
public double getWidth() {
return image.getWidth();
}
In the readObject method, (inside the stream "s") I'm able to see an incoming FSTObjectInput with a wrappedStack of one object: this as hoped contains a SerializableImage in the "toRead" field. However, I'm uncertain how to get this out and into my BufferedImage:
BufferedImage bufferedImage = ImageIO.read(s);
Hence, currently, the image comes back null. I tried adding an FSTInput, but couldn't get it to work. Thanks for any help.

Record and play h.264 video in memory using Jcodec

I am working on a project that requires h.264 video to be written to memory and then read from memory. In other words, using a byte array rather than a File. The only java encoder library that I can find is JCodec.
I am using version 0.2.0 of JCodec's SequenceEncoder8Bit and FrameGrab8Bit classes to read and write to a byte array. The error that I am currently getting is
java.io.IOException: Could not find movie meta information box
at org.jcodec.containers.mp4.demuxer.MP4Demuxer.findMovieBox(MP4Demuxer.java:56)
at org.jcodec.containers.mp4.demuxer.MP4Demuxer.<init>(MP4Demuxer.java:46)
at ....
My code example is as follows:
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.jcodec.api.FrameGrab8Bit;
import org.jcodec.api.JCodecException;
import org.jcodec.api.SequenceEncoder8Bit;
import org.jcodec.common.io.ByteBufferSeekableByteChannel;
import org.jcodec.common.io.SeekableByteChannel;
import org.jcodec.common.model.Picture8Bit;
import org.jcodec.common.model.Rational;
import org.jcodec.scale.AWTUtil;
import org.opencv.core.Mat;
public class Sequence8BitTest {
private static boolean _isDone = false;
public static void main(String[] args) {
byte[] data = writeVideo();
readVideo(data);
}
private static void encodeVideo(SequenceEncoder8Bit encoder, ByteBuffer buffer, int videoSize){
try{//Close Encoder
encoder.finish();
buffer = ByteBuffer.wrap(Arrays.copyOf(buffer.array(), videoSize));
}catch(IOException e){
e.printStackTrace();
}
}
private static BufferedImage matToBufferedImage(Mat in) throws IOException {
byte[] data = new byte[in.width() * in.height() * (int)in.elemSize()];
int type;
BufferedImage out;
in.get(0, 0, data);
if(in.channels() == 1){
type = BufferedImage.TYPE_BYTE_GRAY;
}
else{
type = BufferedImage.TYPE_3BYTE_BGR;
}
out = new BufferedImage(in.width(), in.height(), type);
out.getRaster().setDataElements(0, 0, in.width(), in.height(), data);
return out;
}
private static BufferedImage readImage(FrameGrab8Bit grabber) {
Picture8Bit pic = null;
try {
pic = grabber.getNativeFrame();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return AWTUtil.toBufferedImage8Bit(pic);
}
private static void readVideo(byte[] data){
FrameGrab8Bit grabber = null;
BufferedImage img;
ByteBuffer buffer;
SeekableByteChannel channel;
buffer = ByteBuffer.wrap(data);
channel = new ByteBufferSeekableByteChannel(buffer);
try {
grabber = FrameGrab8Bit.createFrameGrab8Bit(channel);
while((img = readImage(grabber)) != null){
//display Image
}
channel.close();
} catch (IOException | JCodecException e) {
e.printStackTrace();
System.exit(-1);
}
}
private static void writeImage(Mat mat, SequenceEncoder8Bit encoder){
try{//Mat -> BufferedImage -> Picture8Bit
BufferedImage img = matToBufferedImage(mat);
Picture8Bit pic = AWTUtil.fromBufferedImageRGB8Bit(img);//this is the
encoder.encodeNativeFrame(pic); //only constructor that won't crash
}catch(Exception e){
e.printStackTrace();
}
}
public static byte[] writeVideo(){
int fps = 25;
int videoSize = 300_000;//allocated for buffer --> think max size
ByteBuffer buffer = ByteBuffer.allocate(videoSize);
Mat mat = new Mat();
SeekableByteChannel channel = new ByteBufferSeekableByteChannel(buffer);
SequenceEncoder8Bit enc = null;
try {// new SequenceEncoder..
enc = new SequenceEncoder8Bit(channel, new Rational(fps, 1));
enc.getEncoder().setKeyInterval(fps);
while(!_isDone){//Here, grabbing mat frames from camera using JavaCV
writeImage(mat, enc);
}
encodeVideo(enc, buffer, (int)channel.position());
} catch (IOException e1) {
e1.printStackTrace();
}
return buffer.array();
}
}
I looked into the code base and the call to SequenceEncoder8Bit.finish() does write a header to the buffer. Not sure why I can't get the metadata. Anyone out their familiar with this stuff?

Serialization of an arraylist which contains another arraylist

my research on google-search and stackoverflow regarding this problem didn't resolve it.
i'd like to show you a snipped of my Datastructure:
there's a class, called "SequenceHolder" => this one carries an:
ArrayList<SequenceData> data;
within the Sequenceholder, there is a function to call the serialization:
public void writeSequenceList() throws FileNotFoundException, IOException {
FileOutputStream fout = new FileOutputStream(path);
ObjectOutputStream oout = new ObjectOutputStream(fout);
oout.writeObject(data);
oout.close();
fout.close();
}
The class SequenceObject has following fields: (this one is on the top, where i start the serialization)
private ArrayList<SequenceModel> recordedSequenceData;
private String sequenceUrl;
while the SequenceModel is defined like this:
private Object sequenceRawData;
private boolean isProcessedByRequest;
The sequenceRawdata objects are basically two other classes (containing Strings only)!
every class of this "trail" implements the interface "Serializable".
this is the deserialization:
public ArrayList<SequenceData> loadSequenceList() throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
this.data = (ArrayList<SequenceData>) in.readObject();
in.close();
fileIn.close();
return data; // load from de-serialization
}
after a deserialization of the SequenceObject, i'll only retrieve the "sequenceUrl", but no recordedSequenceData.
Is there a trick to do this?!
It came just up to my mind, to extend some classes with the ObjectOutputStream and call the writingprocess with "this" explicitly in every class - but yeah, i am not sure if thats a good idead.
What do you mean by "The sequenceRawdata objects are basically two other classes (containing Strings only)!" because when I try to run the same program :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
class SequenceModel implements Serializable
{
public SequenceModel(Object a, boolean b)
{
sequenceRawData = a;
isProcessedByRequest = b;
}
public String toString()
{
return (String)sequenceRawData + isProcessedByRequest + " SeqModel ";
}
private Object sequenceRawData;
private boolean isProcessedByRequest;
}
class SequenceData implements Serializable
{
public SequenceData(ArrayList<SequenceModel> a, String b)
{
recordedSequenceData = a;
sequenceUrl = b;
}
public String toString()
{
return recordedSequenceData + sequenceUrl + " SeqData ";
}
private ArrayList<SequenceModel> recordedSequenceData;
private String sequenceUrl;
}
class SequenceHolder implements Serializable
{
ArrayList<SequenceData> data;
public String toString()
{
return data + " SeqHol ";
}
public SequenceHolder(ArrayList<SequenceData> a)
{
data = a;
}
public void writeSequenceList() throws FileNotFoundException, IOException {
FileOutputStream fout = new FileOutputStream(Test.file);
ObjectOutputStream oout = new ObjectOutputStream(fout);
oout.writeObject(data);
oout.close();
fout.close();
}
public ArrayList<SequenceData> loadSequenceList() throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream(Test.file);
ObjectInputStream in = new ObjectInputStream(fileIn);
this.data = (ArrayList<SequenceData>) in.readObject();
in.close();
fileIn.close();
return data; // load from de-serialization
}
}
public class Test
{
public static File file = new File("abc.txt");
public static void main(String[] args)
{
SequenceModel obj = new SequenceModel("abc", false);
ArrayList list = new ArrayList(); list.add(obj);
SequenceData obh = new SequenceData(list, "str");
ArrayList l2 = new ArrayList();
l2.add(obh);
SequenceHolder obi = new SequenceHolder(l2);
try {
obi.writeSequenceList();
System.out.println(obi.loadSequenceList());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
it is able to serialize and deserialize both and there is no problem.
Output it is printing is : [[abcfalse SeqModel ]str SeqData ] which includes everything as desired.
Please let me know if I am missing anything.

Saving internet icon then re-opening causes EOF with image4j

I'm currently working on a project where I'm attempting to download a .ico file, but for some strange reason, I can't seem to open it programmatically once downloaded. I can however, open the image saved using any image editor or viewer. My code:
public static BufferedImage parseImageLocal(String url) throws IOException {
if (url.endsWith(".ico")) {
return ICODecoder.read(new File(url)).get(0);
} else if (url.endsWith(".bmp")) {
return BMPDecoder.read(new File(url));
} else {
return ImageIO.read(new File(url));
}
}
public static void saveImage(BufferedImage img, String path)
throws IOException {
File outputfile = new File(path.replace("http://", ""));
File parent = outputfile.getParentFile();
parent.mkdir();
if (!outputfile.exists()) {
outputfile.createNewFile();
}
if (path.endsWith(".ico")) {
ICOEncoder.write(img, outputfile);
} else if (path.endsWith(".bmp")) {
BMPEncoder.write(img, outputfile);
} else {
ImageIO.write(img, "png", outputfile);
}
}
And this is how i download images from the internet:
public static BufferedImage parseImage(String url) throws IOException {
URL dest = new URL(url);
if (url.endsWith(".ico")) {
return ICODecoder.read(dest.openStream()).get(0);
} else if (url.endsWith(".bmp")) {
return BMPDecoder.read(dest.openStream());
} else {
return ImageIO.read(dest);
}
}
The error is on this line:
return ICODecoder.read(new File(url)).get(0);
It "seems" that you are trying to download the icon from the internet, but you are trying to treat the URL as a File.
Basically, this isn't going to be possible, File won't be able to resolve to an actual physical file.
Instead, you should be using ICODecoder#read(InputStream) and URL#openStream
Something more like...
BufferedImage img = null;
InputStream is = null;
try {
// url begin an instance of java.net.URL
is = url.openStream();
img = ICODecoder.read(is);
} finally {
try {
is.close();
} catch (Exception exp) {
}
}
return img;
Updated with example
A web resource is not a File, you can not access it as if they were, instead, you need to use the classes designed for interacting with the internet/network.
For example...
import java.awt.EventQueue;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import net.sf.image4j.codec.ico.ICODecoder;
public class ReadFavicon {
public static void main(String[] args) {
new ReadFavicon();
}
public ReadFavicon() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
try {
BufferedImage img = readIcon(new URL("https://secure.gravatar.com/favicon.ico"));
JOptionPane.showMessageDialog(null, "My FAVICON", "Icon", JOptionPane.PLAIN_MESSAGE, new ImageIcon(img));
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public BufferedImage readIcon(URL url) throws IOException {
BufferedImage img = null;
InputStream is = null;
try {
// url begin an instance of java.net.URL
is = url.openStream();
List<BufferedImage> imgs = ICODecoder.read(is);
img = imgs != null ? imgs.size() > 0 ? imgs.get(0) : null : null;
} finally {
try {
is.close();
} catch (Exception exp) {
}
}
return img;
}
}
Update with some more ideas
Now. I could be wrong, but when I ran your code, I ran into a serious of problems with the paths...
Let's assume the original url/path is https://secure.gravatar.com/favicon.ico, when you save the image, you do something like...
File outputfile = new File(path.replace("http://", ""));
File parent = outputfile.getParentFile();
parent.mkdir();
With our original path, this would result in a outputfile of https://secure.gravatar.com/favicon.ico, which is obviously wrong...
We can correct for this by using path.replace("https://", "") as well...
path = path.replace("http://", "");
path = path.replace("https://", "");
File outputfile = new File(path);
File parent = outputfile.getParentFile();
parent.mkdir();
Now, this results in a outputfile of secure.gravatar.com/favicon.ico. I become a little unstuck, as I'm not sure if this is what you want...but it does work for me...
Now, when you read the file, you do something like this...
public static BufferedImage parseImage(String url) throws IOException {
URL dest = new URL(url);
if (url.endsWith(".ico")) {
return ICODecoder.read(dest.openStream()).get(0);
} else if (url.endsWith(".bmp")) {
return BMPDecoder.read(dest.openStream());
} else {
return ImageIO.read(dest);
}
}
Now, with no evidence to the contray, I have to assume the url has not changed and is still https://secure.gravatar.com/favicon.ico...this means that new File("https://secure.gravatar.com/favicon.ico") will produce an invalid file reference
So, again, I parsed the input...
url = url.replace("https://", "");
url = url.replace("http://", "");
File outputfile = new File(url);
String parentPath = outputfile.getParent();
String name = outputfile.getName();
url = parentPath + File.separator + name;
Which produces secure.gravatar.com\favicon.ico
This all downloaded, wrote and read without error.

serializing a list of objects into a file in java

I have a list of around 20,000 object, which in turn have a very huge hierarchy. I need to dump the objects into a file, so that i can read it later anytime during my process. Now my problem is, I have worked on Java but not that much on serialization and i dont have that much of knowledge how to do that.
In this case as far as i know, i need to use both Serialization ane De-Serialization. Can anyone please help. Also i can use any new API or normal Java Serialization.
Regards.
Look at this link http://www.java2s.com/Code/Java/File-Input-Output/Objectserialization.htm
Its something like this:
Card3 card = new Card3(12, Card3.SPADES);
System.out.println("Card to write is: " + card);
try {
FileOutputStream out = new FileOutputStream("card.out");
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(card);
oos.flush();
} catch (Exception e) {
System.out.println("Problem serializing: " + e);
}
Card3 acard = null;
try {
FileInputStream in = new FileInputStream("card.out");
ObjectInputStream ois = new ObjectInputStream(in);
acard = (Card3) (ois.readObject());
} catch (Exception e) {
System.out.println("Problem serializing: " + e);
}
System.out.println("Card read is: " + acard);
Don't forget to implement Serializable interface in all class you want to save
and put modifier "transient" at all fields you don't want to save.
(e.g. private transient List cache;)
Rather than saving every object individually you can directly save the list of objects. I am using below code to achieve this. Although I am serializing for cloning, it should be sufficient to learn the basics.
public static List<EmpoyeeTO> deepCloneList( List<EmpoyeeTO> objectList) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(objectList);
oos.flush();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (List<EmpoyeeTO>) ois.readObject();
}catch(EOFException eof){
return objectList;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
JSON is all the rage recently so you can use that. Jackson is a nice api for JSON serialization/deserialization. As a bonus you get interoperability with other platforms.
If you're not affraid of xml use JAXB
Of course you can always use binary serialization, but IMO text is easier to manage than blobs.
below is the code to write objects to file using XMLEncoder, assuming that your object implements Serializable Interface.
FileOutputStream os =new FileOutputStream("c:/temp/serialized.xml");
XMLEncoder encoder=new XMLEncoder(os);
encoder.writeObject(objectToBeSerialized);
encoder.close();
Below is the code to deserializ the Data
FileInputStream is=new FileInputStream("c:/temp/serialized.xml");
XMLDecoder decoder=new XMLDecoder(is);
Object object=(Object)decoder.readObject();
decoder.close();
I give you a sample
import java.io.Serializable;
public class Account implements Serializable {
private int accountNo;
private String custName;
private int balance;
/** Creates a new instance of Account */
public Account(int accNo, String name, int bal) {
this.accountNo = accNo;
this.custName = name;
this.balance = bal;
}
#Override
public String toString() {
String str = "Account No:" + this.accountNo;
str += "\nCustomer name:" + this.custName;
str += "\nBalance:" + this.balance;
return str;
}
}
Write and read object
package me.dev;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public void writeObject(ArrayList<Object> listAccount) throws IOException {
//Create FileOutputStream to write file
FileOutputStream fos = new FileOutputStream("C:\\bank.datum");
//Create ObjectOutputStream to write object
ObjectOutputStream objOutputStream = new ObjectOutputStream(fos);
//Write object to file
for (Object obj : listAccount) {
objOutputStream.writeObject(obj);
objOutputStream.reset();
}
objOutputStream.close();
}
public ArrayList<Account> readObject() throws ClassNotFoundException, IOException {
ArrayList<Account> listAccount = new ArrayList();
//Create new FileInputStream object to read file
FileInputStream fis = new FileInputStream("C:\\bank.datum");
//Create new ObjectInputStream object to read object from file
ObjectInputStream obj = new ObjectInputStream(fis);
try {
while (fis.available() != -1) {
//Read object from file
Account acc = (Account) obj.readObject();
listAccount.add(acc);
}
} catch (EOFException ex) {
//ex.printStackTrace();
}
return listAccount;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws ClassNotFoundException {
try {
// TODO code application logic here
ArrayList<Object> listAcc = new ArrayList<Object>();
listAcc.add(new Account(1, "John", 1000));
listAcc.add(new Account(2, "Smith", 2000));
listAcc.add(new Account(3, "Tom", 3000));
Main main = new Main();
main.writeObject(listAcc);
ArrayList<Account> listAccount = main.readObject();
System.out.println("listisze:" + listAccount.size());
if (listAccount.size() > 0) {
for (Account account : listAccount) {
System.out.println(((Account) account).toString());
}
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Categories

Resources