反序列化存储在android

时间:2016-02-11 13:39:25

标签: java android serialization deserialization indexoutofboundsexception

我在将ArrayLists存储和检索到设备的内部存储时遇到了一些麻烦。我有一个自定义的序列化器/反序列化器,我已成功使用它来存储和检索SharedPreferences中的数据。但是,我无法使用存储在设备内部存储中的文件。我需要做出这一步,因为我的日期对于SharedPreferences而言变得太大了。

我非常感谢这个问题的一些帮助。我的代码可能有一个明显的问题,因为我对此很新,并且从未尝试过存储和从Android内部存储中检索(尝试将其作为业余爱好)。任何帮助将不胜感激......

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

serialiser / deserialiser是这样的:

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 void storeToFile(Context ctx, String fileName, ArrayList input) {
    String fileName2 = fileName + ".ser";
    try (
        OutputStream os = ctx.openFileOutput(fileName2, Context.MODE_PRIVATE);
        OutputStream buffer = new BufferedOutputStream(os);
        ObjectOutput output = new ObjectOutputStream(buffer);
        ){
          output.writeChars(ObjectSerializer.serialize(input));
    } catch (FileNotFoundException | IOException e) {
        e.printStackTrace();
    }
}

在加载文件时,在这种情况下,列出了一天的日期&#39;对象:

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

当加载文件时,此时包含并清空ArrayList会抛出致命的ArrayIndexOutOfBounds错误:

  

02-11 13:24:43.460 18966-18966 / com.ctech.dailybread E / AndroidRuntime:FATAL EXCEPTION:main                                                                         过程:com.ctech.dailybread,PID:18966                                                                         java.lang.RuntimeException:无法启动活动ComponentInfo {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)                                                                             at java.lang.reflect.Method.invoke(Native Method)                                                                             在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:length = 15;指数= 15                                                                             在com.ctech.dailybread.io.ObjectSerializer.decodeBytes(ObjectSerializer.java:66)...

...在对象序列化器中引用此行...

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

0 个答案:

没有答案