Reputation: 97
I have a list of a custom object class that I called Students, and I would like to save it in a way such that it won't be affected when we close the app completely. The class: (of course I have a constructor and stuff, but these are the fields that may be important)
public class Students implements Serializable{
private int ID;
private int imageId;
private String firstName;
private String lastName;
private Map<Date, Boolean> Attendance;
My attempt in saving and reading it (inside an activity):
public Boolean saveStudent(Students s) {//saves student into fileName (data.bin)
ObjectOutputStream oos = null;
try {
File file = new File(this.getFilesDir().toString(), fileName);
file.createNewFile();
if(!file.mkdir()){ //just to check whats the reason behind the failed attempt
Toast.makeText(this, "Security Issue", Toast.LENGTH_SHORT).show();
}
FileOutputStream fos = this.openFileOutput(fileName, this.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
return true;
} catch (FileNotFoundException err) {
Toast.makeText(this, "Something went wrong while saving", Toast.LENGTH_SHORT).show();
return false;
} catch (Exception abcd) {
Toast.makeText(this, "Ooops, I don't know what's the problem. Sorry about that!", Toast.LENGTH_SHORT).show();
return false;
}
finally {//makes sure to close the ObjectOutputStream
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public Students readStudent() {//reads Student object from(data.bin) and returns it.
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("data.bin"));
ois.close();
return (Students) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
When I run, it gives me the "Something went wrong while saving" and "Security Issue". Can some one help me solve this problem?
PS: I really don't wanna use an SQLlite database because I think that it's an overkill for just 3 or 4 entries. I hope it's not one of those stupid mistakes that take several hours of staring to find out.
Upvotes: 2
Views: 608
Reputation: 111
Please check this source. I have tested it, and it is working well.
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Students students = new Students();
students.setID(1234);
students.setFirstName("hello");
Log.d("test", "pre students="+students);
saveStudent(students);
Students s = readStudent();
Log.d("test", "after students="+s);
}
String fileName = "data.bin";
public Boolean saveStudent(Students s) {//saves student into fileName (data.bin)
ObjectOutputStream oos = null;
try {
/* File file = new File(this.getFilesDir().toString(), fileName);
file.createNewFile();
if(!file.mkdir()){ //just to check whats the reason behind the failed attempt
Toast.makeText(this, "Security Issue", Toast.LENGTH_SHORT).show();
}*/
FileOutputStream fos = this.openFileOutput(fileName, this.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
return true;
} catch (FileNotFoundException err) {
Toast.makeText(this, "Something went wrong while saving", Toast.LENGTH_SHORT).show();
return false;
} catch (Exception abcd) {
Toast.makeText(this, "Ooops, I don't know what's the problem. Sorry about that!", Toast.LENGTH_SHORT).show();
return false;
}
finally {//makes sure to close the ObjectOutputStream
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public Students readStudent() {//reads Student object from(data.bin) and returns it.
ObjectInputStream ois = null;
Students students = new Students();
try {
/*ois = new ObjectInputStream(new FileInputStream("data.bin"));*/
ois = new ObjectInputStream(openFileInput(fileName));
students = (Students) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return students;
}
}
And for saving and loading multiple objects, please check this link How do I save and multiple objects from a single file?
Upvotes: 2
Reputation: 341
No need to file.mkdir()
Give openFileOutput
an absolutePath may be good.
Check here:
File file = new File(this.getFilesDir().toString(), fileName);
file.createNewFile();
//if(!file.mkdir()){ //just to check whats the reason behind the failed attempt
// Toast.makeText(this, "Security Issue", Toast.LENGTH_SHORT).show();
//}
// Use file.getAbsolutePath()
FileOutputStream fos = this.openFileOutput(file.getAbsolutePath(), this.MODE_PRIVATE);
oos =oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.close();
fos.close();
return true;
And in the read method you should give an absolute file path
check this line : ois = new ObjectInputStream(new FileInputStream("data.bin"));
pass more information to the new FileInputStream("data.bin")
change to :new FileInputStream(new File(getContext().getFilesDir(),"data.bin"));
Do not forget the parent dir.
Upvotes: 1