java 将多个对象写入和读取到文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16473856/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:04:19  来源:igfitidea点击:

Write and read multiple objects to file

javaandroidfileobject

提问by Marek

I am designing an handwriting application for android.

我正在为 android 设计一个手写应用程序。

I would like to write information (class LogInfo) into a log file, every time the user presses the enter button.

我想将信息 ( class LogInfo) 写入日志文件,每次用户按下 Enter 按钮时。

After that, I would like to read the stored information.

之后,我想读取存储的信息。

This is part of my class with a custom write method:

这是我的课程的一部分,具有自定义写入方法:

public class LogInfo implements Serializable {

private static final long serialVersionUID = -5777674941129067422L;

public static List<Point[][]> strokes;
public static List<byte[]> codes;

// Only write and read methods shown

private void writeObject(ObjectOutputStream stream) throws IOException
{
    stream.defaultWriteObject();
    stream.writeInt(strokes.size());
    Point[][] pointsArray = null;
    for (int i = 0; i < strokes.size(); i++)
    {
        pointsArray = ((Point[][])strokes.get(i));
        stream.writeInt(pointsArray.length);
        for (int j = 0; j < pointsArray.length; j++)
        {
            stream.writeInt(pointsArray[j].length);
            for (int k = 0; k < pointsArray[j].length; k++)
            {
                stream.writeInt(pointsArray[j][k].x);
                stream.writeInt(pointsArray[j][k].y);
                //stream.writeObject(elementData[i]);
            }
        }
    }

    int size = codes.size();
    stream.writeInt(size);
    for (int i = 0; i < size; i++)
    {
        stream.write(codes.get(i));
    }
}

This is the read method:

这是读取方法:

private void readObject(java.io.ObjectInputStream stream)
    {
        stream.defaultReadObject();
        int strokesSize = stream.readInt();
        for (int i = 0; i < strokesSize; i++)
        {
            int arrayXSize = stream.readInt();
            Point[][] points = new Point[arrayXSize][];
            for (int j = 0; j < arrayXSize; j++)
            {
                int arrayYSize = stream.readInt();
                points[j] = new Point[arrayYSize];
                for (int k = 0; k < arrayYSize; k++)
                    points[j][k] = new Point(stream.readInt(), stream.readInt());
            }
            strokes.add(points);
        }

        int codesSize = stream.readInt();
        for (int i = 0; i < codesSize; i++)
        {
            byte[] buffer = new byte[3];
            stream.read(buffer, 0, 3);
            codes.add(buffer);
        }
    }

It works well when I save only one object in the file. When I try to save more, reading is not working (it throws a StreamCorruptedException). It reads only one object in the while loop!

当我只在文件中保存一个对象时,它运行良好。当我尝试节省更多时,阅读不起作用(它会抛出StreamCorruptedException)。它只读取 while 循环中的一个对象!

In the main class, I just use two simple methods:

在主类中,我只使用了两个简单的方法:

// WRITE TO FILE
logInfo.writeLog();

// READ FROM FILE
ArrayList<LogInfo> logInfoArrayList = logInfo.readLog();

defined as:

定义为:

public void writeLog()
{
    File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), "data.log");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(file, true);
        //fos = openFileOutput(Environment.getExternalStorageDirectory().getAbsolutePath() + "/data.log", Context.MODE_APPEND);
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(this);
        os.close(); 
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public ArrayList<LogInfo> readLog()
{
    ArrayList<LogInfo> logInfoArray = new ArrayList<LogInfo>();

    try{
        File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), "data.log");
        FileInputStream fis  = new FileInputStream(file);
        ObjectInputStream reader = new ObjectInputStream(fis);  

        LogInfo tempLogInfo = new LogInfo();
        while((tempLogInfo = (LogInfo)reader.readObject()) != null)
            logInfoArray.add(tempLogInfo);
        reader.close();
    } catch (Exception e) {
     //TODO Auto-generated catch block
     e.printStackTrace();
    }

    return logInfoArray;
}

requested UPDATE:

请求更新:

//We use this class to not write a header in a file that already exist
class MyObjectOutputStream extends ObjectOutputStream {

    public MyObjectOutputStream(OutputStream os) throws IOException {
        super(os);
      }

    @Override
    protected void writeStreamHeader() {}
}

回答by user207421

  1. You can't append to an existing file created with an ObjectOutputStream, at least not without effort. There is a trick somewhere about extending ObjectOutputStreamand overriding the writeStreamHeader()method so as not to write the stream header the second time, but I'm not in favour of it. You should really rewrite the whole file, maybe as a List.

  2. You don't need all this code. Just make strokesand codesnon-static and non-transient, and get rid of the readObject()and writeObject()methods altogether.

  1. 您不能附加到使用 . 创建的现有文件ObjectOutputStream,至少不是不费吹灰之力。在某处有一个关于扩展ObjectOutputStream和覆盖该writeStreamHeader()方法的技巧,以免第二次写入流标头,但我不赞成它。你真的应该重写整个文件,也许作为一个列表。

  2. 您不需要所有这些代码。只需 makestrokescodesnon-static 和 non-transient,并完全摆脱readObject()andwriteObject()方法。

回答by handrenliang

@EJP is right.it cannot append to an existing file created with an ObjectOutputStream. You can do the following steps to fix it: 1. keep ObjectOutputStream object reference 2. after writeObject() having been called, do not call close() 3. provide a method to close ObjectOutputStream.

@EJP 是对的。它不能附加到用 ObjectOutputStream 创建的现有文件。您可以执行以下步骤来修复它: 1. 保留 ObjectOutputStream 对象引用 2. 调用 writeObject() 后,不要调用 close() 3. 提供关闭 ObjectOutputStream 的方法。

回答by Mohammad Barbast

there is a way to save multiple objects in one file: you should first make an object array (Object [] objects) and then put your objects one-by-one as an Object in this array and then write this array using writeObject(objects)method. good luck.

有一种方法可以将多个对象保存在一个文件中:您应该首先创建一个对象数组(Object [] objects),然后将您的对象一个一个作为对象放入该数组中,然后使用writeObject(objects)方法写入该数组。祝你好运。