2016-07-05 2 views
3

Wenn ich versuche, die Karte des Typs map[mapKey]string in eine Datei mit gob Encoder zu speichern, speichert es keine Zeichenfolge in der Datei.Nicht in der Lage, Daten in der Datei ordnungsgemäß zu speichern mit Gob

Hier ist mapKey Struct und Map-Wert ist lange JSON-String.

type mapKey struct{ 
    Id1 string 
    Id2 string 
} 

Und wann immer ich bin, anstatt der Struktur verschachtelte Karte verwenden wie:

var m = make(map[string]map[string]string) 

Es funktioniert gut und Speicher Zeichenfolge richtig. Ich bin mir nicht sicher, was ich hier vermisse.

-Code kodiert, dekodiert und in Datei speichern:

func Save(path string, object interface{}) error { 
    file, err := os.Create(path) 
    if err == nil { 
     encoder := gob.NewEncoder(file) 
     encoder.Encode(object) 
    } 
    file.Close() 
    return err 
} 

// Decode Gob file 
func Load(path string, object interface{}) error { 
    file, err := os.Open(path) 
    if err == nil { 
     decoder := gob.NewDecoder(file) 
     err = decoder.Decode(object) 
    } 
    file.Close() 
    return err 
} 

func Check(e error) { 
    if e != nil { 
     _, file, line, _ := runtime.Caller(1) 
     fmt.Println(line, "\t", file, "\n", e) 
     os.Exit(1) 
    } 
} 
+1

Und warum Sie als nicht verwenden verschachtelte Karte. Wahrscheinlich muss die Eingabe wie eine verschachtelte Karte sein. –

+0

@SimoEndre: Gemäß https://blog.golang.org/go-maps-in-action blog schlagen sie vor, Struct zu verwenden, wenn Sie eine verschachtelte Kartentypenstruktur für das Mapping haben. Allerdings bin ich neu in Go und ich bin mir nicht sicher, ob ich die Struktur verwenden kann oder nicht. Es gibt keinen Kompilierungsfehler, aber die lange Zeichenfolge wird nicht gespeichert. – rohan

Antwort

4

Es gibt nichts, bei der Codierung einen Wert vom Typ map[mapKey]string Besonderes ist.

Sehen Sie dieses sehr einfaches Arbeitsbeispiel, das den angegebenen Leser/Schreiber verwendet:

func save(w io.Writer, i interface{}) error { 
    return gob.NewEncoder(w).Encode(i) 

} 
func load(r io.Reader, i interface{}) error { 
    return gob.NewDecoder(r).Decode(i) 
} 

Testen Sie es mit einem In-Memory-Puffer (bytes.Buffer):

m := map[mapKey]string{ 
    {"1", "2"}: "12", 
    {"3", "4"}: "34", 
} 
fmt.Println(m) 

buf := &bytes.Buffer{} 
if err := save(buf, m); err != nil { 
    panic(err) 
} 

var m2 map[mapKey]string 
if err := load(buf, &m2); err != nil { 
    panic(err) 
} 
fmt.Println(m2) 

Ausgabe als erwartet (versuchen Sie es auf der Go Playground):

map[{1 2}:12 {3 4}:34] 
map[{1 2}:12 {3 4}:34] 

haben Sie eine Arbeit Code, aber wissen Sie, dass Sie Load() mit einem Zeigerwert aufrufen müssen (sonst wäre Decoder.Decode() nicht in der Lage, seinen Wert zu ändern).

auch ein paar Dinge, die es zu verbessern:

  • In Ihrem Beispiel sind beim Schlucken Sie die error zurück von Encoder.Encode() (es überprüfen und Sie werden sehen, was das Problem ist, ein häufiges Problem wird mit einem struct mapKey ohne exportierte Felder, in diesem Fall würde ein Fehler von gob: type main.mapKey has no exported fields zurückgegeben werden).
  • Auch sollten Sie File.Close() als eine verzögerte Funktion aufrufen.
  • Auch wenn das Öffnen der Datei fehlschlägt, sollten Sie früh zurückkehren und Sie sollten die Datei nicht schließen.

Dies ist die korrigierte Version des Codes:

func Save(path string, object interface{}) error { 
    file, err := os.Create(path) 
    if err != nil { 
     return err 
    } 
    defer file.Close() 
    return gob.NewEncoder(file).Encode(object) 
} 

func Load(path string, object interface{}) error { 
    file, err := os.Open(path) 
    if err != nil { 
     return err 
    } 
    defer file.Close() 
    return gob.NewDecoder(file).Decode(object) 
} 

Testing es:

m := map[mapKey]string{ 
    {"1", "2"}: "12", 
    {"3", "4"}: "34", 
} 
fmt.Println(m) 

if err := Save("testfile", m); err != nil { 
    panic(err) 
} 

var m2 map[mapKey]string 
if err := Load("testfile", &m2); err != nil { 
    panic(err) 
} 
fmt.Println(m2) 

Ausgabe als erwartet:

map[{1 2}:12 {3 4}:34] 
map[{1 2}:12 {3 4}:34] 
+0

Ich würde vorschlagen, zu überprüfen, ob Sie Zeiger wie Icza hier beschrieben - unter anderem sehr gute Vorschläge verwenden. – TehSphinX

Verwandte Themen