Java 反序列化android中存储的文件时遇到问题

Java 反序列化android中存储的文件时遇到问题,java,android,serialization,deserialization,indexoutofboundsexception,Java,Android,Serialization,Deserialization,Indexoutofboundsexception,我在将ArrayList存储和检索到设备的内部存储器时遇到了一些问题。我有一个自定义序列化器/反序列化器,我已经成功地使用它存储和检索来自SharedReferences的数据。但是,我无法使其与存储在设备内部存储器上的文件一起工作。我需要迈出这一步,因为我的约会日越来越大,无法进行共享参考 我非常感谢在这个问题上给予一些帮助。我的代码可能有一个明显的问题,因为我对这一点很陌生,以前从未尝试过从Android内部存储中存储和检索(作为一种爱好尝试)。任何帮助都将不胜感激 有明显的问题吗?有更好的

我在将ArrayList存储和检索到设备的内部存储器时遇到了一些问题。我有一个自定义序列化器/反序列化器,我已经成功地使用它存储和检索来自SharedReferences的数据。但是,我无法使其与存储在设备内部存储器上的文件一起工作。我需要迈出这一步,因为我的约会日越来越大,无法进行共享参考

我非常感谢在这个问题上给予一些帮助。我的代码可能有一个明显的问题,因为我对这一点很陌生,以前从未尝试过从Android内部存储中存储和检索(作为一种爱好尝试)。任何帮助都将不胜感激

有明显的问题吗?有更好的方法吗

序列化器/反序列化器如下所示:

package com.ctech.dailybread.io;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectSerializer {

private static final Log log = LogFactory.getLog(ObjectSerializer.class);

public static String serialize(Serializable obj) throws IOException {
    if (obj == null) return "";
    ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
    ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
    objStream.writeObject(obj);
    objStream.close();
    return encodeBytes(serialObj.toByteArray());
}

public static Object deserialize(String str) throws IOException, ClassNotFoundException {
    if (str == null || str.length() == 0) return null;
    ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
    ObjectInputStream objStream = new ObjectInputStream(serialObj);
    return objStream.readObject();
}

public static String encodeBytes(byte[] bytes) {
    StringBuffer strBuf = new StringBuffer();

    for (int i = 0; i < bytes.length; i++) {
        strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
        strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
    }

    return strBuf.toString();
}

public static byte[] decodeBytes(String str) {
    byte[] bytes = new byte[str.length() / 2];
    for (int i = 0; i < str.length(); i+=2) {
        char c = str.charAt(i);
        bytes[i/2] = (byte) ((c - 'a') << 4);
        c = str.charAt(i+1);
        bytes[i/2] += (c - 'a');
    }
    return bytes;
}

}
在本例中,加载文件时,会显示“日”对象列表:

public static ArrayList<Day> loadDayListFromFile(Context ctx) {
    InputStream is = null;
    try {
        is = ctx.openFileInput("dayList.ser");
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is, "UTF8"));
            dayList = (ArrayList<Day>) ObjectSerializer.deserialize(reader.toString());
        } catch (IOException | ClassNotFoundException e) {
            Toaster.toastItShort("Unable to load day list", ctx);
            e.printStackTrace();
        }
    } catch (FileNotFoundException e) {
        Toaster.toastItShort("Could not find day list file", ctx);
        e.printStackTrace();
    }


    return dayList;
}
publicstaticarraylistloaddaylistfromfile(Context-ctx){
InputStream=null;
试一试{
is=ctx.openFileInput(“dayList.ser”);
试一试{
Reader Reader=新的BufferedReader(新的InputStreamReader(即“UTF8”));
dayList=(ArrayList)ObjectSerializer.deserialize(reader.toString());
}捕获(IOException | ClassNotFoundException e){
Toaster.toastItShort(“无法加载日期列表”,ctx);
e、 printStackTrace();
}
}catch(filenotfounde异常){
Toaster.toastItShort(“找不到日期列表文件”,ctx);
e、 printStackTrace();
}
返回日列表;
}
加载文件时(此时包含空的ArrayList),会抛出致命的ArrayIndexOutOfBounds错误:

02-11 13:24:43.460 18966-18966/com.ctech.dailybread E/AndroidRuntime:致命异常:main 流程:com.ctech.dailybread,PID:18966 java.lang.RuntimeException:无法启动活动组件信息{com.ctech.dailybread/com.ctech.dailybread.activities.ProgressDetail}:java.lang.ArrayIndexOutOfBoundsException:length=15;指数=15 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)上 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)上 在android.app.ActivityThread.access$800(ActivityThread.java:144) 在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 位于android.os.Handler.dispatchMessage(Handler.java:102) 位于android.os.Looper.loop(Looper.java:135) 位于android.app.ActivityThread.main(ActivityThread.java:5221) 位于java.lang.reflect.Method.invoke(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)上 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 原因:java.lang.ArrayIndexOutOfBoundsException:长度=15;指数=15 在com.ctech.dailybread.io.ObjectSerializer.decodeBytes(ObjectSerializer.java:66)上

。。。在对象序列化程序中引用此行

bytes[i/2] = (byte) ((c - 'a') << 4);

bytes[i/2]=(byte)((c-'a')建议:了解单元测试。显然,您的代码在某些输入下是错误的(异常告诉您使用的索引无效;可能是因为/2…可能并不总是提供您所需的准确字节数)。这些东西非常适合进行单元测试。你可以在eclipse中测试所有这些内容;你不需要考虑任何“android”。附带问题:为什么所有方法都是公开的?建议:了解单元测试。显然,在某些输入下,你的代码是错误的(异常告诉您使用的索引无效;可能是因为/2…可能并不总是提供您所需的确切字节数)。此类内容非常适合进行单元测试。您可以在eclipse中测试所有这些内容;您不需要考虑任何“安卓”。附带问题:为什么所有方法都是公共的?
bytes[i/2] = (byte) ((c - 'a') << 4);