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