I want my app to store multiple objects locally for later use.
Now, my problem is that I know how to load an object from an ObjectInputStream by taking the entire file(federations.dat). Is there a way for me to load say object WHERE id = N from "federations.dat" ? Or do I have to create separate files for each object?
This is my load method:
public static Object load(Context ctx, String filename) throws FileNotFoundException
{
Object loadedObj = null;
InputStream instream = null;
instream = ctx.openFileInput(filename);
try {
ObjectInputStream ois = new ObjectInputStream(instream);
loadedObj = ois.readObject();
return loadedObj;
} catch (StreamCorruptedException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
Any suggestions come to mind ?
You can use it like this..
ArrayList<Object> arrayList = new ArrayList<Object>();
Object obj = null;
while ((obj = ois.readObject()) != null) {
arrayList.add(obj);
}
You can return an ArrayList on your method.
return arrayList;
Edit:
Full code would be like this..
public static ArrayList<Object> load(Context ctx, String filename)
{
InputStream fis = null;
ObjectInputStream ois = null;
ArrayList<Object> arrayList = new ArrayList<Object>();
Object loadedObj = null;
try {
fis = ctx.openFileInput(filename);
ois = new ObjectInputStream(fis);
while ((loadedObj = ois.readObject()) != null) {
arrayList.add(loadedObj);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (null != ois) ois.close();
if (null != fis) fis.close();
}
return arrayList;
}
Hope it helps..
An extention to #Jan 's code, fixing the problem of keeping ois open if an exception is thrown, along with some minor issues.
public static ArrayList<Object> load(Context ctx, String filename) throws FileNotFoundException {
InputStream instream = ctx.openFileInput(filename);
ArrayList<Object> objects = new ArrayList<Object>();
try {
ObjectInputStream ois = new ObjectInputStream(instream);
try{
Object loadedObj = null;
while ((loadedObj = ois.readObject()) != null) {
objects.add(loadedObj);
}
return objects;
}finally{
ois.close();
}
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
Related
This code is used to copy an instance through java serialization. It uses the traditional try-catch-finally writing method. Can it be changed to try-with-resources form?(The DeepConcretePrototype in the code is an ordinary java object)
/**
* Clone an instance through java serialization
* #return
*/
public DeepConcretePrototype deepCloneBySerializable() {
DeepConcretePrototype clone = null;
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutputStream = null;
ByteArrayInputStream byteArrayInputStream = null;
ObjectInputStream objectInputStream = null;
try {
//Output an instance to memory
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
objectOutputStream.flush();
//Read instance from memory
byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
objectInputStream = new ObjectInputStream(byteArrayInputStream);
clone = (DeepConcretePrototype)objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (objectOutputStream != null) {
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (byteArrayInputStream != null) {
try {
byteArrayInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (objectInputStream != null) {
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return clone;
}
Yes you can use try-with-resources, but it's a little tricky because the success of read depends on the success of write. One way you can write it is with a nested try:
public DeepConcretePrototype deepCloneBySerializable() {
DeepConcretePrototype clone = null;
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) {
//Output an instance to memory
objectOutputStream.writeObject(this);
objectOutputStream.flush();
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)) {
//Read instance from memory
clone = (DeepConcretePrototype) objectInputStream.readObject();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return clone;
}
This question already has answers here:
Appending to an ObjectOutputStream
(6 answers)
Closed 5 years ago.
I have a program utilizing the memento design pattern and want to save the state of each object into a file using serialization and return the object back. The problem is that I get a "java.io.StreamCorruptedException: invalid type code: AC" exception due to corrupt headers. I looked at Appending to an ObjectOutputStream and tried to implement the class but still can't get the program to work properly. Multiple objects should be saved in a file and the user passes a string into a function which should match part of the object's string representation.
public class Caretaker implements Serializable {
public void addMemento(Memento m) {
try {
// write object to file
FileOutputStream fos = new FileOutputStream("ConeOutput1.txt", true);
BufferedOutputStream outputBuffer = new BufferedOutputStream(fos);
AppendableObjectOutputStream objectStream = new AppendableObjectOutputStream(outputBuffer);
objectStream.writeObject(m);
objectStream.reset();
objectStream.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public Memento getMemento(String temp) {
try {
Memento result = null;
FileInputStream fis = new FileInputStream("ConeOutput1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
result = (Memento) ois.readObject();
while (result != null) {
Matcher m = Pattern.compile(temp).matcher(result.toString());
if (m.find()) {
return result;
}
else {
result = (Memento) ois.readObject();
}
ois.close();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
You should only use the appending ObjectOutputStream if the file already exists with data in it. If the file is new it needs the object stream header.
when I use readObject I get OptionalDataException (An attempt was made to read an object when the next element in the stream is primitive data), how do I fix this? Page is Serializable. writeObject works.
public Map<Long,Page<byte[]>> readAllPages(){
ObjectInputStream in = null;
try
{
in= new ObjectInputStream(new FileInputStream(HardDisk.getDefault_File_Name()));
#SuppressWarnings("unchecked")
Map<Long, Page<byte[]>> readMap = (Map<Long, Page<byte[]>>)in.readObject(); // exception here
return readMap;
}
catch(Exception ex)
{
ex.printStackTrace();
System.exit(0);
return null;
}
finally
{
if(in != null)
{
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void writeAllPages(Map<Long,Page<byte[]>> hd){
ObjectOutputStream out = null;
try
{
out = new ObjectOutputStream(new FileOutputStream(HardDisk.getDefault_File_Name()));
out.writeObject(hd);
}
catch(Exception ex)
{
ex.printStackTrace();
System.exit(0);
}
finally
{
if(out != null)
{
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The problem was that the class that has the read method extends ObjectInputStream so I shouldn't also create the "in" object, I deleted it and exchanged it with "this" and the problem was solved!
My idea is that I want to read an object from a serialized file located in a server. How to do that?
I can only read .txt file using the following code :
void getInfo() {
try {
URL url;
URLConnection urlConn;
DataInputStream dis;
url = new URL("http://localhost/Test.txt");
// Note: a more portable URL:
//url = new URL(getCodeBase().toString() + "/ToDoList/ToDoList.txt");
urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
dis = new DataInputStream(urlConn.getInputStream());
String s;
while ((s = dis.readLine()) != null) {
System.out.println(s);
}
dis.close();
} catch (MalformedURLException mue) {
System.out.println("Error!!!");
} catch (IOException ioe) {
System.out.println("Error!!!");
}
}
You can do this with this method
public Object deserialize(InputStream is) {
ObjectInputStream in;
Object obj;
try {
in = new ObjectInputStream(is);
obj = in.readObject();
in.close();
return obj;
}
catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
catch (ClassNotFoundException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
feed it with urlConn.getInputStream() and you'll get the Object. DataInputStream is not fit to read serialized objets that are done with ObjectOutputStream. Use ObjectInputStream respectively.
To write an object to the file there's another method
public void serialize(Object obj, String fileName) {
FileOutputStream fos;
ObjectOutputStream out;
try {
fos = new FileOutputStream(fileName);
out = new ObjectOutputStream(fos);
out.writeObject(obj);
out.close();
}
catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
I am trying to store my ArrayList between runtimes. So when I enter items into the ArrayList then close the program down and then open it back up and try to search the item I put in it will still be there.
I have tried MySQL and XML but I cannot figure it out. If you could please direct me in the direction of an easy way to store ArrayList that would be amazing.
Edit:
I am trying to serialize this ArrayList:
static ArrayList<Product> Chart=new ArrayList<Product>();
with these objects:
double Total;
String name;
double quantity;
String unit;
double ProductPrice;
Look into object serialization, it sounds like exactly what you want
What is object serialization?
This allows you to write a Java object to a file and read it back in later.
Here is an example. It also zips up the file, although you don't have to do that. You can also use the stream to write to a MYSQL blob instead of a file.
public static <T> void writeToGZIP(String filename, T obj) {
ObjectOutputStream os = null;
try {
os = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(filename)));
os.writeObject(obj);
System.out.println("Object written to " + filename);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) { os.flush(); os.close(); }
} catch (IOException e) {
e.printStackTrace();
}
}
}
#SuppressWarnings("unchecked")
public static <T> T readFromGZIP(String filename, T obj) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new GZIPInputStream(new FileInputStream(filename)));
obj = (T) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if( ois != null ) ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return obj;
}
ObjectOutputStream and ObjectInputStream