简体   繁体   English

使用FileInputStream读取多个对象-Java

[英]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. 这是我为MainActivity制作的简单onCreate方法,该方法将在按下不同按钮时简单地调用函数,这样我就可以知道发生问题的时间,并根据要访问的数据创建Toast。 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. 下面是我的writeUser方法,该方法接受一个用户,并将其作为对象写入到我使用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. 这是我的readAllUsers()方法,该方法要获取将两个对象添加到的文件,并检索文件中的用户。

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). 这里的错误是当我在readAllUsers中调用第二个Toast时,或更具体地说,当我调用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. 程序说没有索引1,因为长度只有1。我在这里很困惑,因为我的do:while循环应该遍历文件,然后在有要读取的Users时将每个User添加到recordList中。

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. 所以我的问题是:我第二次调用writeUser来覆盖文件以始终只有一个用户,如果是的话,我将如何更改代码,以便将多个Users保留在一个文件中,然后从一个文件中检索全部用户。

If that isn't possible, a point in the right direction would be much appreciated. 如果不可能,朝正确方向的一点将不胜感激。 Thanks 谢谢

So my question is: is my second call of writeUser overwriting the file to only have one user at all time? 因此,我的问题是:我的第二次writeUser覆盖文件是否始终只有一个用户吗?

Yes that's clearly the problem. 是的,这显然是问题所在。 Each time you write a User , the way you do it overwrites the previous file. 每次您写入User ,您执行的方式都会覆盖先前的文件。

[...] 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.) 您可能需要在内存中保留一个List<User>并每次保存该列表(覆盖文件),或者您可以尝试一次一个User 附加到文件中, 有关详细信息 ,请参见此答案 (请确保阅读所有详细信息,这有点棘手,例如,您需要先创建文件,然后将其追加,等等)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM