向文件写入和读取多个对象[英] Write and read multiple objects to file

本文是小编为大家收集整理的关于向文件写入和读取多个对象的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在为Android设计手写应用程序.

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

之后,我想阅读存储的信息.

这是我班级的一部分,使用自定义写方法:

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));
    }
}

这是读取方法:

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);
        }
    }

当我在文件中仅保存一个对象时,它可以很好地工作.当我尝试节省更多时,阅读不起作用(它会引发StreamCorruptedException). 它在while循环中仅读取一个对象!

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

// WRITE TO FILE
logInfo.writeLog();

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

定义为:

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;
}

请求的更新:

//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() {}
}

推荐答案

  1. 您无法将其附加到使用ObjectOutputStream创建的现有文件,至少不是无需努力.扩展ObjectOutputStream并覆盖writeStreamHeader()方法的地方有一个技巧,以免第二次编写流标头,但我不支持它.您应该真正重写整个文件,也许是列表.

  2. 您不需要所有这些代码.只需制作strokes和codes非静态和非传输,然后完全摆脱readObject()和writeObject()的方法.

其他推荐答案

@ejp是正确的.您可以执行以下步骤来修复它: 1.保持ObjectOutputStream对象参考 2. writeObject()被调用后,请勿调用Close() 3.提供关闭ObjectOutputStream的方法.

其他推荐答案

有一种方法可以将多个对象保存在一个文件中:您应该首先制作一个 对象阵列(Object [] objects),然后将对象按对象作为对象作为对象,然后使用writeObject(objects)方法编写此数组. 祝你好运.

本文地址:https://www.itbaoku.cn/post/102578.html

问题描述

I am designing an handwriting application for android.

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

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!

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() {}
}

推荐答案

  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 ObjectOutputStream and 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 strokes and codes non-static and non-transient, and get rid of the readObject() and writeObject() methods altogether.

其他推荐答案

@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.

其他推荐答案

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.