2011-01-19 13 views
10

Jestem nowicjuszem w Javie, więc nie jestem pewien, jak najlepiej to zrobić. Mam strukturę danych, którą chciałbym móc zapisać do pliku przed zamknięciem programu, a następnie odczytać z pliku, aby ponownie wypełnić strukturę przy następnym uruchomieniu aplikacji.Java: Zapisywanie/odczytywanie mapy z dysku

Moja struktura to HashMap<String, Object>. Obiekt jest dość prosty; Dla zmiennych składowych ma łańcuch i dwie małe tablice rodzime typu Boolean. Jest to naprawdę prosta aplikacja i nie spodziewałbym się więcej niż 10-15 <key,value> par jednocześnie.

Eksperymentowałem (bez powodzenia) ze strumieniami wejścia/wyjścia obiektu. Czy muszę zrobić Serializowalną klasę Object?

Czy możesz dać mi jakieś sugestie na najlepszy sposób, aby to zrobić? Potrzebuję tylko pchnięcia we właściwym kierunku. Dzięki!

EDYCJA: Cóż, czuję się głupio, pisząc z jednej mapy i czytając na innej mapie, a następnie porównując je, aby sprawdzić moje wyniki. Najwyraźniej porównywałem ich do błędów. Westchnienie.

+1

HashMap jest już Serializable. Co poszło nie tak podczas próby zapisu do ObjectOutputStream? – finnw

+0

Strumienie wejścia/wyjścia obiektu nie są jedyną dostępną metodą. Czy konkretnie potrzebujesz porady na temat ich używania? Lub ogólnie w ogóle we/wy? – Raedwald

+0

@Raedwald - Naprawdę po prostu szukam najlepszego sposobu na prostą aplikację. Google doprowadziło mnie do strumieni obiektów. – jazz99

Odpowiedz

26

Jeśli nie interesuje Cię w szczególności obiekt, potrzebujesz tylko pary wartości klucza String, String, więc proponuję, aby przejść do java.util.Properties. w przeciwnym razie kliknij tutaj

 Map map = new HashMap(); 
     map.put("1",new Integer(1)); 
     map.put("2",new Integer(2)); 
     map.put("3",new Integer(3)); 
     FileOutputStream fos = new FileOutputStream("map.ser"); 
     ObjectOutputStream oos = new ObjectOutputStream(fos); 
     oos.writeObject(map); 
     oos.close(); 

     FileInputStream fis = new FileInputStream("map.ser"); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     Map anotherMap = (Map) ois.readObject(); 
     ois.close(); 

     System.out.println(anotherMap); 
+1

Zdecydowanie nie używam rozszerzenia .ser, spróbuję tego. Dzięki – jazz99

+1

Przetestowałem ten kod, działa i musi :) –

+0

Wydaje się, że rozszerzenie .ser rozwiązało mój problem. Teraz będę musiał przeczytać o tym, dlaczego tak jest. Dostajesz wygraną. – jazz99

0

Tak, jeśli chcesz zapisać obiekt w systemie plików, obiekt ten musi implementować Serializeable. Here to samouczek, który powinien ci pomóc.

+0

Nie trzeba implementować 'Serializeable'. Tylko jeśli chcesz, aby format serializacji Java był formatem pliku, jest tak w przypadku. – Raedwald

+2

Czy nie tego chciał pytający? Grał ze strumieniami wejścia/wyjścia Object ... – Davidann

+0

Dzięki za tutorial. Czytam teraz! – jazz99

1

Tak, twoje obiekty będą musiały zaimplementować Serializable, aby można je było serializować za pomocą domyślnego mechanizmu Java. HashMap i String implementują już ten interfejs, dzięki czemu mogą być pomyślnie serializowane.

Spójrz na własną Sun Serialization tutorial - jest dość krótki i myślę, że powinien obejmować wszystko, czego potrzebujesz do swojego prostego przypadku. (Powinieneś być w stanie serializować obiekt Map do strumienia, a następnie odczytać go z powrotem w kolejnych przebiegach).

Jeśli napotkasz problemy, spróbuj serializować prosty HashMap<String, String> z pewnymi fałszywymi wartościami. Jeśli to się uda, będziesz wiedział, że problem leży (w jakiś sposób) z serializacją twojej własnej klasy; Alternatywnie, jeśli to nie działa, możesz skupić się na podstawowej strukturze, zanim wrzucisz własną klasę do miksu.

Odeślij ponownie, jeśli masz więcej konkretnych problemów, których sam nie możesz rozwiązać.

0

Nie przejmuj się nad tym, aby było ono szeregowalne, dopóki nie dowiesz się więcej o tym, do czego służy. Chcesz spojrzeć na FileWriter i google "java file io" Dobrym sposobem na zapisanie tych danych jest CSV.

np.

klucz1, klucz2, Key3 valuea1, valuea2, valuea3 valueb1, valueb2, valueb3

Nadzieja to pomaga.

+0

dlaczego csv jest lepszym rozwiązaniem niż serializacja? serializacja nie wymaga dodatkowego kodu, podczas gdy sam/a będziesz musiał/napisać kod formatujący/parsujący CSV. – jtahlborn

+0

Mamy tendencję do unikania obiektów szeregowalnych, chyba że absolutnie musimy z nich korzystać. Jest w nich coś więcej, niż ludzie sobie uświadamiają. Podobnie jak w Raedwald jestem pod wpływem "Efektywnej Jawy" Blocha. – Speck

+2

csv ma ​​własne pułapki. jak uciec przed ogranicznikiem? jak uciec przed ucieczką? etc ... nadal nie kupuj tego jako lepszej alternatywy dla czegoś tak prostego. – jtahlborn

2
Map m = new HashMap(); 
// let's use untyped and autoboxing just for example 
m.put("One",1); 
m.put("Two",2); 

ObjectOutputStream oos = new ObjectOutputStream(
     new FileOutputStream("foo.ser") 
); 
oos.writeObject(m); 
oos.flush(); 
oos.close(); 
0

Odradzam używanie Serializable; jest o wiele trudniej zrobić to lepiej, niż się wydaje. Wydaje się, że wystarczy tylko dodać implements Serializable.Ale w rzeczywistości powoduje to wiele ograniczeń w twoim kodzie, które są trudne do opanowania w praktycznym rozwoju oprogramowania (a nie w szkole). Aby zobaczyć, jak straszne są te ograniczenia, zobacz książkę Bloch'a.

+1

Zgadzam się, że Serializable nie jest skuteczny w przypadku wyjątkowo trwałych danych, ale dla trwałości czasowej bez potrzeby zarządzania zapytaniami lub danymi, myślę, że to działa dobrze. – Xailor

-1

SERIALIZUJ HASHMAP: Ten kod działa poprawnie, zaimplementowałem i użyłem w mojej aplikacji. Plz tworzy funkcje ur odpowiednio do zapisywania mapy i pobierania mapy.

Chodzi o to, że musisz potwierdzić, że obiekty, które umieszczasz jako wartość na mapie, muszą być przekształcalne do postaci szeregowej, co oznacza, że ​​powinny implementować interfejs serailizbele. dawny. Mapa < .String, String> hashmap = new HashMap < .String, String>() .. tutaj w tym wierszu ... mapa i łańcuch znaków są implicite serializowalne, więc nie musimy implementować serializble dla nich jawnie, ale jeśli umieść własny obiekt, który musi być możliwy do serializacji.


public static void main(String arr[]) 
{ 
    Map<String,String> hashmap=new HashMap<String,String>(); 
hashmap.put("key1","value1"); 
    hashmap.put("key2","value2"); 
    hashmap.put("key3","value3"); 
    hashmap.put("key4","value4"); 

    FileOutputStream fos; 
    try { 
     fos = new FileOutputStream("c://list.ser"); 

    ObjectOutputStream oos = new ObjectOutputStream(fos); 
    oos.writeObject(hashmap); 
    oos.close(); 

    FileInputStream fis = new FileInputStream("c://list.ser"); 
    ObjectInputStream ois = new ObjectInputStream(fis); 
    Map<String,String> anotherList = (Map<String,String>) ois.readObject(); 

    ois.close(); 

    System.out.println(anotherList); 

} catch (FileNotFoundException e) {e.printStackTrace(); 
} catch (IOException e) {e.printStackTrace(); 
    } catch (ClassNotFoundException e) {e.printStackTrace(); 
    } 

}