【发布时间】:2013-12-15 00:26:43
【问题描述】:
我正在开发一个远程加载数据的 android 项目,将其保存到数组中(如果数据是新的),将其作为可序列化的数据写入磁盘,然后从磁盘读取数据以加载 ArrayList。
有时 ArrayList 会填充数据,有时不会,程序会崩溃。
我收到一个运行时异常,说明:java.land.ClassCastException: java.lang.String cannot be cast to java.io.ObjectStreamClass。
有时我还会收到 java.io.StreamCorruptedException,有时我会收到 EOFException。
通过异常树,它似乎来自这个调用:
personsArray = (ArrayList<Person>) in.readObject();
现在,有时数据加载正常而没有问题,大多数时候程序崩溃。
以下是将数据保存到磁盘的代码:
public static boolean saveFromRemoteSource(Context c, ArrayList<?> source){
//Save context
context = c;
//Save source to local file
File file = context.getFileStreamPath(PERSONS_FILE);
//Status if successful in saving
boolean savedStatus = false;
try {
if(!file.exists()){
file.createNewFile();
}else{
//file already exists so don't do anything
}
//now load the data into the file
FileOutputStream fos = context.openFileOutput(PERSONS_FILE, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(source);
oos.close();
savedStatus = true;
} catch(IOException e){
e.printStackTrace();
savedStatus = false;
}
return savedStatus;
}
这是从磁盘读取数据的代码:
public static boolean loadPersonsArray(Context c){
context = c;
boolean loadStatus = false;
File file = context.getFileStreamPath(PERSONS_FILE);
try{
if(!file.exists()){
file.createNewFile();
}else {
//File is already created, do nothing
}
BufferedReader br = new BufferedReader(new FileReader(file));
if (br.readLine() != null) {
FileInputStream fis = context.openFileInput(PERSONS_FILE);
ObjectInputStream in = new ObjectInputStream(fis);
personsArray = (ArrayList<Person>) in.readObject();
in.close();
fis.close();
loadStatus = true;
}
br.close();
} catch(IOException e){
e.printStackTrace();
Log.d("TAG", "IOException PERSONS_FILE file: " + e);
loadStatus = false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
Log.d("TAG", "ClassNotFoundException PERSONS_FILE file classnotfound: " + e);
}
return loadStatus;
}
这是 Person 类:
import java.io.Serializable;
public class Person implements Serializable, Comparable<Person>{
//Person class
private static final long serialVersionUID = 1L;
private String personID;
private String personName;
private boolean displayPerson;
//default constructor
public Person(){
super();
}
public Person(String personID,
String personName,
boolean displayPerson){
super();
this.personID = personID;
this.personName = personName;
this.displayPerson = displayPerson;
}
//Accessor Methods
public String getPersonID(){
return personID;
}
public String getPersonName(){
return personName;
}
public boolean getDisplayPerson(){
return displayPerson;
}
//setter methods
public void setPersonID(String personID){
this.personID = personID;
}
public void setPersonName(String personName){
this.personName = personName;
}
public void setDisplayPerson(boolean displayPerson){
this.displayPerson = displayPerson;
}
@Override
public String toString(){
return this.getPersonName().replaceAll("[^A-Za-z0-9]", "") + this.getDisplayPerson();
}
public int compareTo(Person otherPerson) {
if(!(otherPerson instanceof Person)){
throw new ClassCastException("Not a valid Person object!");
}
Person tempPerson = (Person)otherPerson;
if(this.getPersonName().compareToIgnoreCase(tempPerson.getPersonName()) > 0){
return 1;
}else if(this.getPersonName().compareToIgnoreCase(tempPerson.getPersonName()) < 0){
return -1;
}else{
return 0;
}
}
}
要写入文件的数据来自哪里
private void downloadPersons(){
HashMap<String, String> params = new HashMap<String, String>();
Kumulos.call("selectAllPersons", params, new ResponseHandler() {
@Override
public void didCompleteWithResult(Object result) {
ArrayList<Object> personsList = new ArrayList<Object>();
for(Object o : (ArrayList<?>)result){
Person person = new Person();
person.setPersonID(replaceNandT((String) ((HashMap<?,?>) o).get("personID")));
person.setLawName(replaceNandT((String) ((HashMap<?,?>) o).get("personName")));
person.setDisplayLaw(stringToBool((String)((HashMap<?,?>) o).get("displayPerson")));
if(person.getDisplayPerson()==true){
personsList.add(person);
}
}
//Save personsList to a file
if(PersonsLoader.saveFromRemoteSource(context, personsList)){
updateVersionNumber();
isFinished=true;
Log.d("TAG", "PersonsLoader.saveFromRemoteSource(context, personsList) success");
}
}
});
}
那么你认为这次电话会议发生了什么?
【问题讨论】:
-
很可能正在写入文件的任何内容都有错误。这听起来很像一个包含损坏簿记信息的文件。
-
这是从磁盘读取数据的代码。写代码在哪里?还有堆栈跟踪?
-
我用这个来保存 File file = ontext.getFileStreamPath(PERSONS_FILE);
-
这还不够。它不保存任何东西。某处还必须有一个打开、一个写入和一个关闭。展示下。将其编辑到您的帖子中。下次当你说“这是将数据保存到磁盘的代码”时,请确保它是真的。
-
错字,应该说“阅读”。随后我添加了“保存”代码。感谢您的快速回复。
标签: java android bufferedreader fileinputstream objectinputstream