4

이 직렬화 가능 클래스를 가지고 있는데, 이진 파일에 문자열의 ArrayList를 저장하는 데 사용합니다.ObjectInputStream이 비어있는 객체를 제공합니다. (읽은 파일이 비어 있지 않습니다.)

public static void saveData(){ 
    ObjectOutput out; 
    try { 
     //primero comprobamos si existe el directorio, y si no, lo creamos. 
     File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME); 
     if(!folder.exists()) 
      folder.mkdirs(); 

     File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data"); 
     out = new ObjectOutputStream(new FileOutputStream(outFile)); 
     out.writeObject(SaveState.instance); 
     out.close(); 
    } catch (Exception e) {e.printStackTrace();} 
} 

을 그리고 마지막으로, 나는에이 방법을 사용 :

public class SaveState implements Serializable{ 
    public static ArrayList <String> favoriteBusStopNumbers = new ArrayList<String>(); 
    public static SaveState instance=new SaveState(); 
} 

나는이 배열은 내가 저장해야하는 데이터 전체되면 문자열의 ArrayList를 가진 인스턴스를 저장하기 위해이 방법을 사용하고 있습니다 내 응용 프로그램의 초기화 파일을로드하고 이전에 저장된 데이터를 내 SaveState.instance 변수를 채우기 위해 : 내가 데이터를 저장하면 파일이 D의 대상 채우기 제대로 생성되는

public static void loadData(){ 
    ObjectInput in; 
    try { 
     File inFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data"); 
     in = new ObjectInputStream(new FileInputStream(inFile));   
     SaveState.instance=(SaveState) in.readObject(); 
     in.close(); 
    } catch (Exception e) {e.printStackTrace();} 
} 

ata, 파일에 디스크 공간이 0KB 이상 있기 때문에 알아. 하지만 내 응용 프로그램을 시작하고 데이터를로드 할 때 SaveState.instance 변수가 빈 ArrayList 문자열을 가져 오므로 뭔가 잘못되고 있습니다. 코드에서 무엇이 잘못 되었습니까?

감사합니다.

답변

6

귀하의 arraylist는 정적입니다. 정적 변수는 클래스와 연관되며 객체와 연관되지 않습니다. 그래서 그들은 직렬화되지 않습니다.

정적 변수를 직렬화하려면, readObject 및 writeObject를 대체해야합니다. 여기 http://java.sun.com/developer/technicalArticles/Programming/serialization/

최고의 솔루션 데이터 구조를 재고하고이 객체의 상태를 저장하면 ArrayList를 비 정적 만드는 것입니다 - 여기

몇 가지 추가 정보입니다.

편집 : (@Ted 아래에서 알 수 있듯이) 또는 그냥 ArrayList를 직렬화 할 수

1

유일한 데이터가 SaveState에 보관하기 때문에 정적 배열, 당신은 단지 직렬화하고 배열을 직렬화 복원 성공이 더있을 것이다 :

public static void saveData(){ 
    ObjectOutput out; 
    try { 
     //primero comprobamos si existe el directorio, y si no, lo creamos. 
     File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME); 
     if(!folder.exists()) 
      folder.mkdirs(); 

     File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data"); 
     out = new ObjectOutputStream(new FileOutputStream(outFile)); 
     out.writeObject(SaveState.favoriteBusStopNumbers); 
     out.close(); 
    } catch (Exception e) {e.printStackTrace();} 
} 

@SuppressWarnings("unchecked") 
public static void loadData(){ 
    ObjectInput in; 
    try { 
     File inFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data"); 
     in = new ObjectInputStream(new FileInputStream(inFile)); 
     SaveState.favoriteBusStopNumbers=(ArrayList<String>) in.readObject(); 
     in.close(); 
    } catch (Exception e) {e.printStackTrace();} 
} 

는 (당신은 제네릭 형식에 캐스팅에 대해 경고를 억제 할 필요가있다.)

당신은 정말 전혀 SaveState.instance 필드가 필요하지 않습니다.

3

문제는 정적으로 표시 변수를 구현하는 당신을 제외하고

private void readObject(ObjectInputStream ois){} 

private void writeObject(ObjectOutputStream oos){} 

를 직렬화되지 않을 것입니다 ObjectOutputStream에 -의 JavaDoc :

의 디폴트의 직렬화기구 object는 클래스, 클래스 서명 및 va 클래스를 씁니다. non-transient 및 비 정적 필드의 루팅