cjnash
cjnash

Reputation: 1248

Reading multiple objects using a FileInputStream - Java

I am trying to write multiple objects (User objects I made) to a file, and then read them off the file later. I created a test app to see if this was easily done, and I am running into problems.

User testUser = new User("cmon", 72, 145, 20, 0);
User testUser2 = new User("second", 72, 145, 20, 0);
List<User> recordList = new ArrayList<User>();
String FILENAME = "test_file.slr";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    save = (Button) findViewById(R.id.Save);
    save2 = (Button) findViewById(R.id.save2);
    load = (Button) findViewById(R.id.load);
    textBox = (EditText) findViewById(R.id.edit_message);

    save.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            writeUser(testUser);
        }
    });

    save2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            writeUser(testUser2);
        }
    });

    load.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            readAllUsers();
        }
    });
}

This is the simple onCreate method I made for my MainActivity, which will simply call functions when different buttons are pressed, just so I can have an idea of when things are going wrong and create Toasts based on data that I want to access. Also above the method is just a couple variables that I have initialized, thought that showing how I made them would possibly come in handy.

Below is my writeUser method, which takes a user, and writes it as an object to a file that I have accessed using FileOutputStream. I also added a toast just so I know that it completed correctly with no exceptions thrown.

public void writeUser(User addingUser){
    try {
        FileOutputStream fou = openFileOutput(FILENAME, Context.MODE_PRIVATE);

        ObjectOutputStream oow = new ObjectOutputStream(fou);
        oow.writeObject(addingUser);
        oow.flush();
        oow.close();

        Toast.makeText(getBaseContext(), "Data Saved of username: " + addingUser.getUserName(), Toast.LENGTH_SHORT).show();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Here is my readAllUsers() method, which I want to take the file that I added the two objects to, and retrieve the users that are in the file.

public void readAllUsers() {
    try {
        FileInputStream fis = openFileInput(FILENAME);

        ObjectInputStream ois = new ObjectInputStream(fis);

        User readCase  = null;

        do{
            readCase = (User)ois.readObject();
            if(readCase != null) {
                recordList.add(readCase);
            }
        } while(ois.available() != 0);

        Toast.makeText(getBaseContext(), "User 1: " + recordList.get(0).getUserName(), Toast.LENGTH_SHORT).show();
        Toast.makeText(getBaseContext(), "User 2: " + recordList.get(1).getUserName(), Toast.LENGTH_SHORT).show();

        ois.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

The error here is when I call the second Toast in readAllUsers, or more specifically, when I call recordList.get(1). The program says that there is no index 1 because the length is only 1. I am confused here because my do:while loop should be going through the file, then adding each User to the recordList while there are Users to be read.

So my question is: is my second call of writeUser overwriting the file to only have one user at all times, and if so how would I change my code so that I can keep multiple Users in one file and then retrieve them all from one file.

If that isn't possible, a point in the right direction would be much appreciated. Thanks

Upvotes: 0

Views: 60

Answers (1)

Hugues M.
Hugues M.

Reputation: 20467

So my question is: is my second call of writeUser overwriting the file to only have one user at all time?

Yes that's clearly the problem. Each time you write a User, the way you do it overwrites the previous file.

[...] and if so how would I change my code so that I can keep multiple Users in one file and then retrieve them all from one file?

You would either need to keep a List<User> in memory and save that list each time (overwriting the file), or, you could try to append one User at a time to your file, see this answer for details (be sure to read all details, it's a bit tricky, for example you need to first create the file then append to it, etc.)

Upvotes: 1

Related Questions