0

Hi Iam having serious issues try to persist some serializable objects to a file on the local android file system. Iam getting a Bad file descriptor error and I think it is to do with my methods for creating the file. the file and checking if the file exists. i create a private file object in the class. Then, on write or read. I check file existance with the following code.

@Override
public boolean fileExists() {

    File file = context.getFileStreamPath(filename);
    return file.exists();
}

this doesnt instantiate my file object called "objectfile"!! but does check the "filename" exists.

to create the file I call this method if "filename" doesnt exist.

  public void createFile()
 {
    objectfile = new File(context.getFilesDir(), filename);
    objectfile.setReadable(true);
    objectfile.setWritable(true);
 }

Iam not sure if this will give me back my previously created file which would be ideally what I want to do. Is there a way i can just get the old file or create a new one and pass it to "objectfile" variable in the constructor??

Iam also wondering what the best way to do this is?? Or should i just use the mysqlite db? using object file persistance doesn't seem to be working out for me right now and iam working to a deadline. Also this method is mention in the gooogle docs so I thought it would be legit was to do it.

http://developer.android.com/training/basics/data-storage/files.html

here is my method for reading the serializable objects

public synchronized ArrayList<RoomItem> readObjects() {

    final ArrayList<RoomItem> readlist =  new ArrayList<>();

    if(!fileExists())
        return readlist;

    if(objectfile == null)
        createFile();

    try {

        finputstream = new FileInputStream(objectfile);
        instream = new ObjectInputStream(finputstream);

        readwritethread = new Thread(new Runnable() {
            @Override
            public void run() {

            try {

                    final ArrayList<RoomItem> readitems  = (ArrayList<RoomItem>)  instream.readObject();

                    instream.close();
                    finputstream.close();

                    handler.post(new Runnable() {
                        @Override
                        public void run() {

                            listener.updateList(readitems);
                       }
                    });

                } catch(IOException e)
                {
                    e.printStackTrace();
                }
                catch(ClassNotFoundException e)
                {
                    e.printStackTrace();
                    Log.d("read failed", "file read failed");
                }
            }
        });

    }
    catch(Exception e)
    {
        e.printStackTrace();
    }


    timeOutReadWrite(readwritethread);
    readwritethread.start();
    try {
        readwritethread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    Log.d("read from file", "file read");
    return readlist;

if anyone could suggest any improvements id really appreciate it. I use a handler to pass back to my activity and implement a listener interface on my activity thats call the activity when all the obj are read. Thanks again!

filthy_wizard
  • 740
  • 11
  • 25
  • Have you tried using `RandomAccessFile` ? Alternatively, have you tried storing data in a SQLite database? – Shark Dec 04 '15 at 13:04
  • havent tried randomaccessfile. sounds a bit random!? i want to read and write consitently to a file of the same name – filthy_wizard Dec 04 '15 at 13:11
  • It is called `RandomAccessFile` because you don't have to read it from byte0 to EOF, but read parts of it starting from the middle if you so choose. It doesn't mean that access to it is randomized; it simply means that random accesses to the file *ARE* allowed. http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html – Shark Dec 04 '15 at 13:16
  • will this command give me back the same file if it is found on the file system " objectfile = new File(context.getFilesDir(), filename);" ????? – filthy_wizard Dec 04 '15 at 13:22

2 Answers2

0

1#: Yes, it will return the original file you created. 2#: Depends on the thing you want to store, seems File is more flex from description

hope helpful.

smart
  • 51
  • 6
0

We have used

FileOutputStream fos = context.openFileOutput("file.ser", Context.MODE_PRIVATE);

to write our serialized files.This will carete files in /data/data/app.package.name/files/. In fact, this path is returned by getFilesDir().

And while deserializing, use

//make sure you pass the same file that was passed to openFileOutput().. FileInputStream fis = context.openFileInput("file.ser");

Also, to avoid confusing between file names you can use name of class that is being serialized.

Ex:

public static <T> void serialize(final Context context, final T objectToSerialize) {
....
....
Strin fileName = objectToSerialize.getClass().getSimpleName();

...
}

Do this and keep the method in util so it can be used for any type of objects (T type) to serialize.

cgr
  • 4,578
  • 2
  • 28
  • 52