Last active
September 4, 2023 09:10
-
-
Save PMaynard/a3ae177fb3d6f39d9c32a62253227f0f to your computer and use it in GitHub Desktop.
Go serialise data to disk using encoding/gob.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Author: Peter Maynard (pete[at]port22[co/uk]) | |
* Date: 2023 September 04 | |
* Summary: | |
* Serialises a structure and writes to disk as a file. | |
* The data can be read back in and accessed as a normal | |
* struct. | |
* | |
* The data stored on disk is plain text so be careful | |
* where you store it | |
* Assocated blog post: https://not.just-paranoid.net/go-serialise-data-to-disk-using-encoding/gob/ | |
First run with no existing file "./data.store" | |
freethink# go run disk-gob.go | |
2023/09/04 09:58:16 Could not find existing store. | |
2023/09/04 09:58:16 DS.Principles Initialised. | |
2023/09/04 09:58:16 Loaded 2 DS.Principles. | |
2023/09/04 09:58:16 Data Store Last Updated on: 0001-01-01 00:00:00 +0000 UTC | |
2023/09/04 09:58:16 example@email.com 65706574 77207361 | |
2023/09/04 09:58:16 another@email.com 68207265 0a650a65 | |
Second run with an existing file "./data.store" | |
freethink# go run disk-gob.go | |
2023/09/04 09:59:14 Loaded 2 DS.Principles. | |
2023/09/04 09:59:14 Data Store Last Updated on: 2023-09-04 09:58:16.034821023 +0100 BST | |
2023/09/04 09:59:14 example@email.com 65706574 77207361 | |
2023/09/04 09:59:14 another@email.com 68207265 0a650a65 | |
freethink# hexdump data.store -C | |
00000000 32 ff 81 03 01 01 05 53 74 6f 72 65 01 ff 82 00 |2......Store....| | |
00000010 01 02 01 09 55 70 64 61 74 65 64 4f 6e 01 ff 84 |....UpdatedOn...| | |
00000020 00 01 0a 50 72 69 6e 63 69 70 6c 65 73 01 ff 88 |...Principles...| | |
00000030 00 00 00 10 ff 83 05 01 01 04 54 69 6d 65 01 ff |..........Time..| | |
00000040 84 00 00 00 2a ff 87 04 01 01 19 6d 61 70 5b 73 |....*......map[s| | |
00000050 74 72 69 6e 67 5d 6d 61 69 6e 2e 50 72 69 6e 63 |tring]main.Princ| | |
00000060 69 70 6c 65 01 ff 88 00 01 0c 01 ff 86 00 00 33 |iple...........3| | |
00000070 ff 85 03 01 02 ff 86 00 01 03 01 05 45 6d 61 69 |............Emai| | |
00000080 6c 01 0c 00 01 0a 50 72 69 76 61 74 65 4b 65 79 |l.....PrivateKey| | |
00000090 01 0c 00 01 09 50 75 62 6c 69 63 4b 65 79 01 0c |.....PublicKey..| | |
000000a0 00 00 00 74 ff 82 01 0f 01 00 00 00 0e dc 87 92 |...t............| | |
000000b0 65 04 68 44 06 00 3c 01 02 06 74 65 73 74 30 31 |e.hD..<...test01| | |
000000c0 01 11 65 78 61 6d 70 6c 65 40 65 6d 61 69 6c 2e |..example@email.| | |
000000d0 63 6f 6d 01 08 36 35 37 30 36 35 37 34 01 08 37 |com..65706574..7| | |
000000e0 37 32 30 37 33 36 31 00 06 74 65 73 74 30 32 01 |7207361..test02.| | |
000000f0 11 61 6e 6f 74 68 65 72 40 65 6d 61 69 6c 2e 63 |.another@email.c| | |
00000100 6f 6d 01 08 36 38 32 30 37 32 36 35 01 08 30 61 |om..68207265..0a| | |
00000110 36 35 30 61 36 35 00 00 |650a65..| | |
00000118 | |
* | |
*/ | |
package main | |
import ( | |
"bufio" | |
"encoding/gob" | |
"errors" | |
"log" | |
"os" | |
"time" | |
) | |
var DS *Store | |
type Store struct { | |
UpdatedOn time.Time | |
Principles map[string]Principle | |
} | |
type Principle struct { | |
Email string | |
PrivateKey string | |
PublicKey string | |
} | |
func main() { | |
filepath := "./data.store" | |
/* 1. Load or create new store. */ | |
DS, err := read(filepath) | |
if err != nil { | |
log.Fatalf("Unable to load saved state: %v", err) | |
} | |
/* 2. Insert some data. */ | |
if len(DS.Principles) == 0 { | |
DS.Principles = make(map[string]Principle) | |
log.Println("DS.Principles Initialised.") | |
DS.Principles["test01"] = Principle{Email: "example@email.com", PrivateKey: "65706574", PublicKey: "77207361"} | |
DS.Principles["test02"] = Principle{Email: "another@email.com", PrivateKey: "68207265", PublicKey: "0a650a65"} | |
} | |
log.Printf("Loaded %d DS.Principles.", len(DS.Principles)) | |
log.Println("Data Store Last Updated on:", DS.UpdatedOn) | |
for _, principle := range DS.Principles { | |
log.Println(principle.Email, principle.PrivateKey, principle.PublicKey) | |
} | |
/* 3. Write to disk. */ | |
err = write(filepath, &DS) | |
if err != nil { | |
log.Fatalf("Unable to write state: %v", err) | |
} | |
} | |
func read(path string) (Store, error) { | |
file, err := os.Open(path) | |
if err != nil { | |
log.Println("Could not find existing store.") | |
return Store{}, nil | |
} | |
fileReader := bufio.NewReader(file) | |
fileDecoder := gob.NewDecoder(fileReader) | |
res := Store{} | |
if err := fileDecoder.Decode(&res); err != nil { | |
return Store{}, errors.New("Unable to decode") | |
} | |
file.Close() | |
return res, nil | |
} | |
func write(path string, data *Store) error { | |
data.UpdatedOn = time.Now() | |
file, err := os.Create(path) | |
if err != nil { | |
return errors.New("Unable to write file") | |
} | |
defer file.Close() | |
fileWriter := bufio.NewWriter(file) | |
fileEncoder := gob.NewEncoder(fileWriter) | |
if err := fileEncoder.Encode(data); err != nil { | |
return errors.New("Unable to encode") | |
} | |
fileWriter.Flush() | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment