Reading objects from assets - java

something is really messed up. I've got a ".ser" document in the assets folder, which stores an ArrayList of Objetcs. In an android application, I want to read this objects. There are a lot of posts related to this issue, however none of them could solve my problem. The strange part is, when I am using similar code in non - android context / "normal" java, it works properly. Here, the last line throws a NullPointerException - What is going wrong?
public void getData() {
ArrayList<MyClass> output= null;
InputStream is = null;
ObjectInputStream ois = null;
try{
is = this.getAssets().open("data.ser");
ois = new ObjectInputStream(is);
output = (ArrayList<MyClass>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("TAG", output.get(0).getId());
}

I would create a class and place the array within a single object:
public class ListObjects implements Serializable {
List<MyClass> listMyClass = new ArrayList<>();
public ListObjects(){
}
public List<MyClass> getListMyClass() {
return listMyClass;
}
public void setListMyClass(List<MyClass> listMyClass) {
this.listMyClass = listMyClass;
}
}
I had a similar problem. And it was because the name of the package in the java app was not called the same as the package name in android. And therefore I did not recognize them as equal objects. This is how I do it:
public static Object fromData(byte[] data) {
ObjectInputStream ois = null;
Object object = null;
try {
ois = new ObjectInputStream(
new ByteArrayInputStream(data));
object = ois.readObject();
} catch (Exception ex) {
Logger.getLogger(ModeloApp.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
ois.close();
} catch (Exception ex) {
Logger.getLogger(ModeloApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
return object;
}

Related

NotSerializableException at simple class implementing Serializable

I'm trying to serialize a simple class Sertest. It has one member Decision which itself has only a boolean and an int member, both classes implement Serializable.
However I get a java.io.NotSerializableException: Decision.
Decision.java:
import java.io.Serializable;
public class Decision implements Serializable {
public final int chosenValue;
public final boolean continuePlaying;
public Decision(int chosenValue, boolean continuePlaying){
this.chosenValue = chosenValue;
this.continuePlaying = continuePlaying;
}
}
Sertest.java:
import java.io.Serializable;
public class Sertest implements Serializable {
private Decision test;
public Sertest(){
this.test = new Decision(1, true);
}
public Decision getTest(){
return test;
}
}
And finally, my Main.java code:
Sertest s = null;
File f = new File("sertest.asdf");
if(f.exists()){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(f));
s = (Sertest) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
else{
s = new Sertest();
ObjectOutputStream oos = null;
try{
oos = new ObjectOutputStream(new FileOutputStream(f));
oos.writeObject(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
if (s != null)
System.out.println(s.getTest().chosenValue);
I searched and searched StackOverflow and Duckduckgo, but just can't find the reason for this. I tried:
Refactoring the Decision class to have private members with getter methods
Adding a noarg-constructor to Decision
Debugging by setting a breakpoint in ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355) (However this didn't work)

Get data from getter method instead of passing in a Bundle

I need to pass some Bitmaps from one activity to another, and, since the size limit of the Bundle won't let me pass these images (even using a byte array*), I thought that I could use a getter method between these Activities.
-But, since I'm still not a master in Android (Java), I don't know if that would make any difference, and, if it does, what should I watch out for when using it.
the byte array did reduce the total size(at about 60%), but it still wasn't enough
scaling down is a way out, but just in case any other solution works
save your object in a file
private void saveDataToFile() {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = getContext().openFileOutput("fileName", Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
}
ObjectOutputStream objectOutputStream = null;
try {
objectOutputStream = new ObjectOutputStream(fileOutputStream);
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
}
try {
if (objectOutputStream != null) {
objectOutputStream.writeObject(yourObject); //which data u want to save
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (objectOutputStream != null) {
objectOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Retrieve the object from another activity
private void getDataFromFile() {
FileInputStream fileInputStream = null;
try {
fileInputStream = getContext().openFileInput("fileName");
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(fileInputStream);
} catch (IOException |NullPointerException e) {
e.printStackTrace();
}
try {
yourObject = (ObjectClass) objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Pass through Uri by writing getter method in POJO class
If you want to use getter setter, just create URI of your bitmap and pass to setter method in POJO class and then retrieve using getter method of POJO class.

Can't create ObjectInputStream

Why can't I create an ObjectInputStream object? Every time I try to create one I get EOFException and I can't figure why. Can someone help me?
Below is the code with which I have the problem and the stack trace obtained from the execution. The file is empty.
public void loadFromFileStudent() throws IOException, ClassNotFoundException {
try{
InputStream inputStream = new FileInputStream("student.txt");
System.out.println(inputStream.toString());
ObjectInputStream objectInputStream;
objectInputStream = new ObjectInputStream(inputStream);
System.out.println(objectInputStream.toString());
this.repo=(Dictionary<Integer, Student>) objectInputStream.readObject();
objectInputStream.close();
inputStream.close();
}catch (EOFException e){
e.printStackTrace();;
//System.out.println(e.getMessage());
}
}
.
java.io.FileInputStream#65ddcac5
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2324)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2793)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:799)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at repository.Repository.loadFromFileStudent(Repository.java:94)
at repository.Repository.<init>(Repository.java:112)
at utils.DataStructure.createRepository(DataStructure.java:16)
at controller.Controller.<init>(Controller.java:9)
at utils.DataStructure.createController(DataStructure.java:20)
at application.RunMenu.<init>(RunMenu.java:15)
at application.App.main(App.java:5)
EOFException is thrown when end-of-file is reached. That is, you have read the whole file. Therefore you should not close your streams within the try statement, but use try-with-resources to automatically close them.
Try something simple like this:
public void loadFromFileStudent() throws IOException, ClassNotFoundException {
try (InputStream inputStream = new FileInputStream("student.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
this.repo = (Dictionary<Integer, Student>) objectInputStream.readObject();
} catch (FileNotFoundException e) {
System.out.println ("File not found");
} catch (IOException e) {
System.out.println ("Error while reading");
} catch (ClassNotFoundException e) {
System.out.println ("No class");
} catch (ClassCastException e) {
System.out.println ("Could not cast to class");
}
}
Writing is equally simple:
public void writeObject ( Object o ) {
try (FileOutputStream fos = new FileOutputStream ( this.filename );
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(o);
oos.flush();
} catch (NotSerializableException e) {
System.out.println ("Object wont be serialized");
e.printStackTrace();
} catch (IOException e) {
System.out.println ("Error while writing to file");
e.printStackTrace();
}
}
From my understanding of the question I assume OP is doing some thing like below, and which should works. May be OP would have missed something during writing/reading. Hope this helps to figure out.
public class Test2 {
public static void main(String[] args) {
Test2 t = new Test2();
t.create();
t.read();
}
public void create(){
try{
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("D:\\test\\ab.txt"));
Student st = new Student("chevs");
Dictionary<Integer, Student> dict = new Hashtable<Integer, Student>();
dict.put(1, st);
os.writeObject(dict);
}catch(Exception e){
e.printStackTrace();
}
}
public void read()
{
try{
InputStream inputStream = new FileInputStream("D:\\test\\a.txt");
System.out.println(inputStream.toString());
ObjectInputStream objectInputStream;
objectInputStream = new ObjectInputStream(inputStream);
System.out.println(objectInputStream.toString());
private Dictionary<Integer, Student> repo=(Dictionary<Integer, Student>) objectInputStream.readObject();
System.out.println(repo.get(1));
objectInputStream.close();
inputStream.close();
}catch (Exception e){
e.printStackTrace();;
}
}
public class Student implements Serializable{
public String name=null;
public Student(String name){
this.name=name;
}
public String toString() {
return name.toString();
}
}
}

Convert byte[] to ArrayList<String>

I found a question here on SO: Convert ArrayList<String> to byte []
It is about converting ArrayList<String> to byte[].
Now is it possible to convert byte[] to ArrayList<String> ?
Looks like nobody read the original question :)
If you used the method from the first answer to serialize each string separately, doing exactly the opposite will yield the required result:
ByteArrayInputStream bais = new ByteArrayInputStream(byte[] yourData);
ObjectInputStream ois = new ObjectInputStream(bais);
ArrayList<String> al = new ArrayList<String>();
try {
Object obj = null;
while ((obj = ois.readObject()) != null) {
al.add((String) obj);
}
} catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the ObjectInputStream
try {
if (ois != null) {
ois.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
If your byte[] contains the ArrayList itself, you can do:
ByteArrayInputStream bais = new ByteArrayInputStream(byte[] yourData);
ObjectInputStream ois = new ObjectInputStream(bais);
try {
ArrayList<String> arrayList = ( ArrayList<String>) ois.readObject();
ois.close();
} catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
//Close the ObjectInputStream
try {
if (ois!= null) {
ois.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Something like this should suffice, forgive any compile typos I've just rattled it out here:
for(int i = 0; i < allbytes.length; i++)
{
String str = new String(allbytes[i]);
myarraylist.add(str);
}
yeah its possible, take each item from byte array and convert to string, then add to arraylist
String str = new String(byte[i]);
arraylist.add(str);
it depends very much on the semantics you expect from such a method. The easiest way would be, new String(bytes, "US-ASCII")—and then split it into the details you want.
There are obviously some problems:
How can we be sure it's "US-ASCII" and not "UTF8" or, say, "Cp1251"?
What is the string delimiter?
What if we want one of the strings to contain a delimiter?
And so on and so forth. But the easiest way is indeed to call String constructor—it'll be enough to get you started.

where android saves serialized objects?

I'm looking for a place where are objects after serialization ? I would like to put serialized objects(created in another app) to my android project and then only load this files in my game. The problem is that I don't know where do I have to put this objects ? and even if I save object from android app it never saves in my project folder. My load and save functions for objects
public static void save(Context context, Map obj, String nazwa)
{
FileOutputStream str = null;
ObjectOutputStream objStr = null;
try {
str = context.openFileOutput(nazwa, Context.MODE_PRIVATE);
objStr = new ObjectOutputStream(str);
objStr.writeObject(obj);
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
try
{
if (objStr != null) objStr.close();
} catch (IOException e) {}
try
{
if (str != null) str.close();
} catch (IOException e) {}
}
}
public static Map load(Context context, String nameFile)
{
Map obj = null;
FileInputStream str_w = null;
ObjectInputStream obj_w = null;
try
{
str_w = context.openFileInput(nameFile);
obj_w = new ObjectInputStream(str_w);
obj = (Map) obj_w.readObject();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} finally
{
try
{
if (obj_w != null) obj_w.close();
} catch (IOException e) {}
try
{
if (str_w != null) str_w.close();
} catch (IOException e) {}
}
return obj;
}
If I copy my object file to /levels/ and use
final Map map2 = MapManager.load(this, "/levels/map1.lvl");
or
final Map map2 = MapManager.load(this, "levels/map1.lvl");
it never works
How should I do it ?
You're storing them as app private files (Context.MODE_PRIVATE) to a folder only the app has access to, so no other application will be able to access them.
I think the easiest way to store them so they can be shared between apps is to store them to the sdcard using:
Environment.getExternalStorageDir();
Be aware to store them as globally readable.

Categories