read serializable custom object into file android - java

i am trying to record and reab back my list into file. It's working great until I restart my application. I am working with simulator (I don't have a real phone under Android)
Here is my function to record my class into a file :
public boolean writeRecordsToFile(String path, DummyContent object){
FileOutputStream fos;
ObjectOutputStream oos = null;
try {
fos = fileContext.openFileOutput(path, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
Log.d("fileManager", "Records write successfully");
return true;
} catch (Exception e) {
Log.e("fileManager", "Cant save records : " + e.getMessage());
return false;
}
finally {
if (oos != null)
try {
oos.close();
} catch (Exception e) {
Log.e("fileManager", "Error while closing stream "+e.getMessage());
}
}
}
Here is my reading Function :
public boolean readRecordsFromFile(String path){
FileInputStream fin;
ObjectInputStream ois=null;
try {
fin = fileContext.openFileInput(path);
ois = new ObjectInputStream(fin);
DummyContent records = (DummyContent) ois.readObject();
records.addItem("test", "test", "test");
ois.close();
Log.d("fileManager", "Records read successfully :\n" + records.toString());
Log.d("fileManager", "nbArticle found : " + String.valueOf(records.ITEMS.size()));
Log.d("fileManager", "article 0 title :\n" + records.ITEMS.get(0).content);
Log.d("fileManager", "article 10 title :\n" + records.ITEMS.get(10).content);
return true;
} catch (Exception e) {
Log.e("fileManager", "Cant read saved records : "+e.getMessage());
return false;
}
finally {
if (ois != null)
try {
ois.close();
} catch (Exception e) {
Log.e("fileManager", "Error in closing stream while reading records : "+e.getMessage());
}
}
}
and here is my class :
public class DummyContent implements Serializable {
/**
* An array of sample (dummy) items.
*/
public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
/**
* A map of sample (dummy) items, by ID.
*/
public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
public void addItem(String first, String second, String third) {
DummyItem dummyItem = new DummyItem(first, second, third, android.R.drawable.ic_input_add);
ITEMS.add(dummyItem);
ITEM_MAP.put(dummyItem.id, dummyItem);
}
public void deleteAll() {
ITEMS = new ArrayList<DummyItem>();
ITEM_MAP = new HashMap<String, DummyItem>();
}
public void changeURL(Long index, String newURL) {
ITEMS.get(index.intValue()).url = newURL;
}
public void changeContent(Long index, String newContent) {
ITEMS.get(index.intValue()).contenu = newContent;
}
/**
* A dummy item representing a piece of content.
*/
public static class DummyItem {
public final String id;
public final String content;
public final String details;
public final int imageResource;
public String url;
public String contenu;
public DummyItem(String id, String content, String details, int imageResource) {
this.id = id;
this.content = content;
this.details = details;
this.imageResource = imageResource;
this.url = "";
this.contenu = "";
}
#Override
public String toString() {
return content;
}
}
}
Finally I read my file at the onCreate of my MainActivity (first activity at the lunching app) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fileManager = new FileManager(this.getApplicationContext());
Log.d("Main", String.valueOf(fileManager.fileExist("Article.art")));
fileManager.readRecordsFromFile("Article.art"); /* Bug here : size of my array is empty but file's size is the same */
}
Here is my console return :
D/fileManager: size = 102
D/fileManager: Records read successfully :
D/fileManager: nbArticle found : 1 (because i add an item at the read
function) E/fileManager: Cant read saved records : Index: 10, Size: 1
I know it is working because when I write and read directly after the writting, I got all my items and I can read several times and I still got all items (this bug semms to be only present when I restart my application)
Maybe can I got help ?
Thanks !

The reason is very easy: You have declared some field as static, which are not covered by standard serialization: So, the contents of these fields were never written nor read from the file. That's why they "dissapeared" after a JVM restart.
Any field you want to be serialized/deserialized, you must declare it as instance member (not static).
See documentation on Serializable.

Related

How do I save a custom class object data model to a different file each time it is made in java?

I have a custom ListView that uses an object class for its data. The users can add new items to the listview, the arraylist is then saved in SharedPreferences. However, I also want to save each individual item so that I can use it in another Expandable ListView, how could I create a file for each individual item the user creates, or perhaps there is a better why to do it? Thanks in advance. Here is the object class:
public class Item implements Serializable{
String homework, date, classes;
public Item(String homework, String date, String classes){
this.homework = homework;
this.date = date;
this.classes = classes;
}
public String getHomework(){
return homework;
}
public String getDate(){
return date;
}
public String getClasses(){
return classes;
}
}
Why not use a database?There is a bit of setting up, but after the initial set up writing/reading data is very easy.
https://developer.android.com/training/basics/data-storage/databases.html
An example of serialize-deserialize class
public final class Serialize
{
private static final String className = Serialize.class.getName();
public static void save(Object saveThis, String serializeFileName, Context context)
{
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try
{
if(saveThis != null)
{
fos = context.openFileOutput(serializeFileName, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(saveThis);
}
}
catch(Throwable t)
{
//log it
}
finally
{
if(oos != null)
{
try{oos.close();}catch(Throwable t){}
}
if(fos != null)
{
try{fos.close();}catch(Throwable t){}
}
}
}
public static Object read(String serializeFileName, Context context)
{
FileInputStream fis = null;
ObjectInputStream ois = null;
Object readThis = null;
try
{
File file = context.getFileStreamPath(serializeFileName);
if(file != null && file.exists())
{
fis = context.openFileInput(serializeFileName);
ois = new ObjectInputStream(fis);
readThis = ois.readObject();
}
}
catch(Throwable t)
{
//log it
}
finally
{
if(ois != null)
{
try{ois.close();}catch(Throwable t){}
}
if(fis != null)
{
try{fis.close();}catch(Throwable t){}
}
}
return readThis;
}
public static boolean delete(String serializeFileName, Context context)
{
boolean deleted = false;
try
{
File file = context.getFileStreamPath(serializeFileName);
if(file != null && (file.exists()))
{
deleted = file.delete();
}
}
catch(Throwable t)
{
//log it
}
return deleted;
}
public static boolean exist(String serializeFileName, Context context)
{
boolean exist = false;
try
{
File file = context.getFileStreamPath(serializeFileName);
if(file != null && (file.exists()))
{
exist = true;
}
}
catch(Throwable t)
{
//log it
}
return exist;
}
}
Use the save method to save the serializable object in a file and the read method to read it.

DCM4CHE, Network operations,Handling a C-Move call

Hi I'm trying to make a PACS server using Java. dcm4che appears to be quite popular. But I'm unable to find any good examples about it.
As a starting point I inspected dcmqrscp and it successfully stores a DICOM image. But I cannot manage to handle a C-MOVE call. Here's my CMove handler. It finds requested the DICOM file adds a URL and other stuff, it doesn't throw any exception yet client doesn't receive any files.
private final class CMoveSCPImpl extends BasicCMoveSCP {
private final String[] qrLevels;
private final QueryRetrieveLevel rootLevel;
public CMoveSCPImpl(String sopClass, String... qrLevels) {
super(sopClass);
this.qrLevels = qrLevels;
this.rootLevel = QueryRetrieveLevel.valueOf(qrLevels[0]);
}
#Override
protected RetrieveTask calculateMatches(Association as, PresentationContext pc, final Attributes rq, Attributes keys) throws DicomServiceException {
QueryRetrieveLevel level = QueryRetrieveLevel.valueOf(keys, qrLevels);
try {
level.validateRetrieveKeys(keys, rootLevel, relational(as, rq));
} catch (Exception e) {
e.printStackTrace();
}
String moveDest = rq.getString(Tag.MoveDestination);
final Connection remote = new Connection("reciverAE",as.getSocket().getInetAddress().getHostAddress(), 11113);
if (remote == null)
throw new DicomServiceException(Status.MoveDestinationUnknown, "Move Destination: " + moveDest + " unknown");
List<T> matches = DcmQRSCP.this.calculateMatches(keys);
if (matches.isEmpty())
return null;
AAssociateRQ aarq;
Association storeas = null;
try {
aarq = makeAAssociateRQ(as.getLocalAET(), moveDest, matches);
storeas = openStoreAssociation(as, remote, aarq);
} catch (Exception e) {
e.printStackTrace();
}
BasicRetrieveTask<T> retrieveTask = null;
retrieveTask = new BasicRetrieveTask<T>(Dimse.C_MOVE_RQ, as, pc, rq, matches, storeas, new BasicCStoreSCU<T>());
retrieveTask.setSendPendingRSPInterval(getSendPendingCMoveInterval());
return retrieveTask;
}
private Association openStoreAssociation(Association as, Connection remote, AAssociateRQ aarq)
throws DicomServiceException {
try {
return as.getApplicationEntity().connect(as.getConnection(),
remote, aarq);
} catch (Exception e) {
throw new DicomServiceException(
Status.UnableToPerformSubOperations, e);
}
}
private AAssociateRQ makeAAssociateRQ(String callingAET,
String calledAET, List<T> matches) {
AAssociateRQ aarq = new AAssociateRQ();
aarq.setCalledAET(calledAET);
aarq.setCallingAET(callingAET);
for (InstanceLocator match : matches) {
if (aarq.addPresentationContextFor(match.cuid, match.tsuid)) {
if (!UID.ExplicitVRLittleEndian.equals(match.tsuid))
aarq.addPresentationContextFor(match.cuid,
UID.ExplicitVRLittleEndian);
if (!UID.ImplicitVRLittleEndian.equals(match.tsuid))
aarq.addPresentationContextFor(match.cuid,
UID.ImplicitVRLittleEndian);
}
}
return aarq;
}
private boolean relational(Association as, Attributes rq) {
String cuid = rq.getString(Tag.AffectedSOPClassUID);
ExtendedNegotiation extNeg = as.getAAssociateAC().getExtNegotiationFor(cuid);
return QueryOption.toOptions(extNeg).contains(
QueryOption.RELATIONAL);
}
}
I added the code below to send a DICOM file as a response:
String cuid = rq.getString(Tag.AffectedSOPClassUID);
String iuid = rq.getString(Tag.AffectedSOPInstanceUID);
String tsuid = pc.getTransferSyntax();
try {
DcmQRSCP.this.as=as;
File f = new File("D:\\dcmqrscpTestDCMDir\\1.2.840.113619.2.30.1.1762295590.1623.978668949.886\\1.2.840.113619.2.30.1.1762295590.1623.978668949.887\\1.2.840.113619.2.30.1.1762295590.1623.978668949.888");
FileInputStream in = new FileInputStream(f);
InputStreamDataWriter data = new InputStreamDataWriter(in);
// !1! as.cmove(cuid,1,keys,tsuid,"STORESCU");
as.cstore(cuid,iuid,1,data,tsuid,rspHandlerFactory.createDimseRSPHandler(f));
} catch (Exception e) {
e.printStackTrace();
}
Throws this exception
org.dcm4che3.net.NoRoleSelectionException: No Role Selection for SOP Class 1.2.840.10008.5.1.4.1.2.2.2 - Study Root Query/Retrieve Information Model - MOVE as SCU negotiated
You should add a role to the application instance like:
applicationEntity.addTransferCapability(
new TransferCapability(null, "*", TransferCapability.Role.SCP, "*"));

Repeated Writing and Loading ArrayList of objects from a file

I have a 'Person' class where i stored data like name, surname etc. I make 5 object type Person, add them to ArrayList, and save this ArrayList to file. Next i'm loading from this file ArrayList and i have 5 person. Problem is when i want save again for example 10 object Person. When i'm loading ArrayList from file i'm getting only 5 person from first writing. If i repeat this still i will have load data from first writing to this file. How i can fix this ?
public class Data {
static List<Person> persons = new ArrayList<Person>();
public static void main(String[] args) throws IOException {
Data.savePersons(5);
Data.loadPersons();
/** Clean 'persons' array for TEST of load data */
persons.removeAll(persons);
System.out.println("\n-----------\nNext Round\n-----------\n");
Data.savePersons(10);
Data.loadPersons();
}
/** Save a couple of Person Object to file C:/data.ser */
public static void savePersons(int noOfPersonToSave) throws IOException {
FileOutputStream fout = null;
ObjectOutputStream oos = null;
/** Make 5 'Person' object and add them to ArrayList 'persons' for example */
for (int i = 0; i < noOfPersonToSave; i++) {
Person personTest = new Person("name" + i, "surname" + i, "email" +i, "1234567890" +i);
persons.add(personTest);
}
try {
fout = new FileOutputStream("C:\\data.ser", true);
oos = new ObjectOutputStream(fout);
oos.writeObject(persons);
System.out.println("Saving '" + persons.size() + "' Object to Array");
System.out.println("persons.size() = " + persons.size());
System.out.println("savePersons() = OK");
} catch (Exception ex) {
System.out.println("Saving ERROR: " + ex.getMessage());
} finally {
if (oos != null) {
oos.close();
}
}
}
/** Load previously saved a couple of Person Object in file C:/data.ser */
public static void loadPersons() throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("C:\\data.ser");
ois = new ObjectInputStream(fis);
persons = (List<Person>) ois.readObject();
//persons.add(result);
System.out.println("-------------------------");
System.out.println("Loading '" + persons.size() + "' Object from Array");
System.out.println("persons.size() = " + persons.size());
System.out.println("loadPersons() = OK");
} catch (Exception e) {
System.out.println("-------------------------");
System.out.println("Loading ERROR: " + e.getMessage());
} finally {
if (ois != null) {
ois.close();
}
}
}}
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String surname;
private String mail;
private String telephone;
public Person(String n, String s, String m, String t) {
name = n;
surname = s;
mail = m;
telephone = t;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getMail() {
return mail;
}
public String getTelephone() {
return telephone;
}}
new FileOutputStream("C:\\data.ser", true)
You're passing true for the append parameter. So you're appending a list of 10 persons to the file, after the already existing list of 5 people. And since you only read one list, you read the first you wrote, which contains 5 persons.
Pass false instead of true.

Print arraylist to text file in HUMAN READABLE form

so i can't figure out how to print an arraylist index (the first index so 0) to a text file. Basically, I have a Job class which stores 5 variables
public class Job {
public int teamNo;
public String regNo;
public String gridRef;
public String gridCopy;
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
and then I have an arraylist of type Job:
private static ArrayList<Job> teamNoOne = new ArrayList<Job>();
So the data all gets added fine, prints it out etc but I can't save it to a text file. this is my code, I just get the random hash code of it but I need it in human readable form.
try {
File file = new File("JOBS-DONE-LOG.txt");
FileOutputStream fs = new FileOutputStream(file);
ObjectOutputStream os = new ObjectOutputStream(fs);
System.out.println(teamNoOne.get(0));
os.writeObject(teamNoOne.get(0));
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Can't figure out how to do it.
writeObject serializes the object in your file, it doesn't write it in textual form (http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeObject(java.lang.Object))
You must do it in another way: for example, you can use the BufferedWriter class and the write method to write the output of your toString() method.
Here is a complete example:
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
public class Job {
public String regNo;
public String gridRef;
public String gridCopy;
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
public static void main(String[] args) throws Exception {
ArrayList<Job> teamNoOne = new ArrayList<Job>();
// fill your array
Job job = new Job();
job.regNo = "123";
// continue to fill the jobs...
teamNoOne.add(job);
BufferedWriter writer = new BufferedWriter(new FileWriter("JOBS-DONE-LOG.txt"));
System.out.println(teamNoOne.get(0));
writer.write(teamNoOne.get(0).toString());
os.close();
}
}
Since you are trying to save an arraylist of type Job, it has to be serialized (Refer this).
public class Job implements java.io.Serializable
{
public int teamNo=0;
public String regNo="default";
public String gridRef="default";
public String gridCopy="default";
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "";
}
}
For Saving the file
try
{
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(teamNoOne);
out.close();
fileOut.close();
}
catch(IOException i)
{
i.printStackTrace();
}
Thus you can load the arraylist back like
Object o = null;
try
{
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
o = in.readObject();
in.close();
fileIn.close();
}
catch(IOException i)
{
i.printStackTrace();
}
catch(ClassNotFoundException c)
{
c.printStackTrace();
}
Arraylist<Job> loaded_Job = (ArrayList<Job>) o;
Then print the arraylist
for(int i = 0; i < loaded_Job.size(); i++) {
loaded_Job.get(i).toString();
}
This happens because you didn't parameterize your ArrayList. Use generics when declaring your list:
ArrayList<Job> teamNoOne = new ArrayList<Job>();
Because now, though you have overriden your toString() method, teamNoOne.get(0) uses an Object's toString().

equivalent to python's shelve module in Java

Is there any module in Java equivalent to python's shelve module? I need this to achieve dictionary like taxonomic data access. Dictionary-like taxonomic data access is a powerful way to save Python objects in a persistently easy access database format. I need something for the same purpose but in Java.
I also needed this, so I wrote one. A bit late, but maybe it'll help.
It doesn't implement the close() method, but just use sync() since it only hold the file open when actually writing it.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
public class Shelf extends HashMap<String, Object> {
private static final long serialVersionUID = 7127639025670585367L;
private final File file;
public static Shelf open(File file) {
Shelf shelf = null;
try {
if (file.exists()) {
final FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
shelf = (Shelf) ois.readObject();
ois.close();
fis.close();
} else {
shelf = new Shelf(file);
shelf.sync();
}
} catch (Exception e) {
// TODO: handle errors
}
return shelf;
}
// Shelf objects can only be created or opened by the Shelf.open method
private Shelf(File file) {
this.file = file;
sync();
}
public void sync() {
try {
final FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(this);
oos.close();
fos.close();
} catch (Exception e) {
// TODO: handle errors
}
}
// Simple Test Case
public static void main(String[] args) {
Shelf shelf = Shelf.open(new File("test.obj"));
if (shelf.containsKey("test")) {
System.out.println(shelf.get("test"));
} else {
System.out.println("Creating test string. Run the program again.");
shelf.put("test", "Hello Shelf!");
shelf.sync();
}
}
}
You could use a serialisation library like Jackson which serialises POJOs to JSON.
An example from the tutorial:
Jackson's org.codehaus.jackson.map.ObjectMapper "just works" for
mapping JSON data into plain old Java objects ("POJOs"). For example,
given JSON data
{
"name" : { "first" : "Joe", "last" : "Sixpack" },
"gender" : "MALE",
"verified" : false,
"userImage" : "Rm9vYmFyIQ=="
}
It takes two lines of Java to turn it into a User instance:
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
User user = mapper.readValue(new File("user.json"), User.class);
Where the User class looks something like this (from an entry on Tatu's blog):
public class User {
public enum Gender { MALE, FEMALE };
public static class Name {
private String _first, _last;
public String getFirst() { return _first; }
public String getLast() { return _last; }
public void setFirst(String s) { _first = s; }
public void setLast(String s) { _last = s; }
}
private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;
public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }
public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }
}

Categories