简体   繁体   中英

Java write and read an array of objects to file

I have a base class named Train :

public abstract class Train {
    String serialNo;
    float weight;
    final String label;

    public Train(String serialNo, float weight, String label) {
        this.serialNo = serialNo;
        this.weight = weight;
        this.label = label;
    }

    public abstract float getCapacity();
}

And I have 2 classes implementing the abstract class(I will not include getters and setters in the code):

public class FreightTrain extends Train implements Cloneable {

    private float capacityKg;
    Vector<String> freightVector = new Vector<String>();

    public FreightTrain(String serialNo, float weight, String label) throws Exception{
        super(serialNo, weight, label);
        if (weight < 0)
            throw new Exception();
    }

    @Override
    public float getCapacity() {
        return this.capacityKg;
    }
}

And the PassengerTrain class:

public class PassengerTrain extends Train implements Cloneable {

    private float seatNo;
    Vector<String> passengerId = new Vector<String>();

    public PassengerTrain(String serialNo, float weight, String label) throws Exception{
        super(serialNo, weight, label);
        if (weight < 0)
            throw new Exception();
    }

    @Override
    public float getCapacity() {
        return this.seatNo;
    }
}

Next I have an array list ArrayList<Train> arr; which contains both: the PassengerTrain and FreightTrain . I want to create methods to write the items from arr to a file and read the data from file

Here is my attempt:

public void writeObjectInTextFile(ArrayList<Train> array) {
    Formatter f = null;
    try {
        f = new Formatter(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    for(Train train: array) {

        if(train instanceof PassengerTrain) {
            String label = train.getLabel();
            String serialNo = train.getSerialNo(); 
            float capacity = train.getCapacity();
            float weight = train.getWeight();
            float seatNo = ((PassengerTrain) train).getSeatNo();
            String passId = "";

            for(String id:((PassengerTrain) train).getPassengerId()) {
                passId += id;
            }

            f.format("%s %f %s %f %f %s", serialNo, weight, label, capacity, seatNo, passId);
        } else if(train instanceof FreightTrain) {
            String label = train.getLabel();
            String serialNo = train.getSerialNo(); 
            float capacity = train.getCapacity();
            float weight = train.getWeight();
            float capacityKg = ((FreightTrain) train).getCapacityKg();
            String freightVector = "";

            for(String freight: ((FreightTrain) train).getFreightVector()) {
                freightVector += freight;
            }

            f.format("%s %f %s %f %f %s", serialNo, weight, label, capacityKg, capacity, freightVector);
        }
    }
    f.close();
}

But I have a problem: I am unable to create a function that will read this data from the file, and return the correct ArrayList with the initial data.

What is the best and fastest way to write the array of 2 different classes deriving from a single class to a file?

And how it could be recreated?

Thank you!

Please don't my question as duplicate. I have searched for similar questions and my question is different from the ones available.

I don't know how to convert back the objects from file to their respective types. What If I have n deriving classes?

Simply have your classes implement Serializable and you'll be ready to write your objects to files (and read them back, of course) whenever you want! This includes arrays of your objects, too.

That's the 10000-foot answer above. Implementing Serializable correctly (in a way that won't come back around to bite you) is a somewhat daunting subject. However, there is plenty of literature out there that can teach you how to do it and how to avoid common pitfalls. I recommend Joshua Bloch's "Effective Java" for this, personally; he's dedicated a whole chapter or two to the subject.

if(train instanceof PassengerTrain) This is bad. You are completely throwing the whole purpose of inheritance and polymorphism away. Your code shouldn't care about what type the trains are.

You should use the Object serialization features of Java. Implement Serializable in your Train class and use ObjectOutputStream to write and ObjectInputStream to read the objects.

Write:

public void writeTrainsToFile(ArrayList<Train> array, String file) {
    FileOutputStream fileOutputStream = new FileOutputStream(file);

    try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)){
        objectOutputStream.writeInt(array.size());
        for(Train train: array) {
            objectOutputStream.writeObject(train);
        }
    }
}

Read:

public void readTrainsFromFile(ArrayList<Train> array, String file) {
    FileInputStream fileInputStream = new FileInputStream(file);

    try(ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)){
        int trainCount = objectInputStream.readInt();
         for (int i = 0; i < trainCount; i++) {
            array.add((Train)objectInputStream.readObject());
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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