I'm storing Message
(struct defined below) inside a file using Gob serialization.
type Message struct {
Message string `json:"message"`
From string `json:"from"`
}
I managed to do this by putting my Message
inside a slice that I serialized using gob, then I store this serialized slice inside a file.
But, by doing this way I need to load my entire serialized slice from the file, decode it, append the new Message
, Encode the slice and save it once again inside the file.
This seems complexe and not well optimized to me..
Function I use to encode / decode and write / read
func (m Message) Encode() ([]byte, error) {
var res bytes.Buffer
encoder := gob.NewEncoder(&res)
err := encoder.Encode(m)
if err != nil {
return []byte{}, err
}
return res.Bytes(), nil
}
func (m Message) Write(path string) error {
messages, err := Read(path)
if err != nil {
return err
}
messages = append(messages, m)
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
defer f.Close()
encoder := gob.NewEncoder(f)
encoder.Encode(messages)
return nil
}
func Read(path string) ([]Message, error) {
f, err := os.OpenFile(path, os.O_RDWR, 0644)
if err != nil {
return []Message{}, err
}
defer f.Close()
m := []Message{}
decoder := gob.NewDecoder(f)
if err = decoder.Decode(&m); err != nil {
if err == io.EOF {
return []Message{}, nil
}
return []Message{}, err
}
return m, nil
}
A solution would be to store serialized Message
directly inside the file and simply append new Message
at the end.
I achived by using os.O_APPEND
to append instead of overwrite the entiere file :
f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
I also made others basics changes like replace []Message with Message and so on..
Now I'm able to store Message
inside my file and simply append new message at the end of the file without rewritting the entiere file each time.
But I have to idea how to read Message
stored inside the file.
Previous code just read the first message and ignore the rest of the file
I found many solutions to read a file line by line but none seems to work with gob serialized object
Is it possible to read a file storing gob serialized object line by line ? Or do I have to stay with my current solution i.e storing a serialized slice ?
Note : I found this topic (Retrieving gobs written to file by appending several times) which look to describe same type of issue but it's almost from 7 years ago + describe a little bit more complexe issue