在源代码中直接使用gobs,这是可能的吗?

huangapple go评论89阅读模式
英文:

use gobs directly in the source code, is it possible?

问题

我想知道是否可以直接在源代码中使用gob编码的数据(例如在函数中)。原因是通过不访问磁盘获取gob文件来提高性能。我知道有memcached、redis等工具,但我不需要TTL或其他高级功能,只需要在内存中使用映射。数据将在“设置/构建”过程中进行编码和转储到源代码中,以便在运行时只需要“解码”它。

这个Go应用程序基本上将作为一个小型的只读嵌入式数据库。我可以使用JSON来实现这一点(基本上声明一个带有原始JSON的变量),但我猜这可能会有性能损失,所以我想知道是否可以使用gob来实现。

我尝试了不同的方法,但我无法使其工作,因为我不知道如何定义gob变量(byte、[bytes]??)而且解码器似乎期望一个io.Reader,所以在花费整天时间之前,我决定先问问你们SO的朋友们是否可能实现。

糟糕的尝试:

var test string
test = "hello"

p := new(bytes.Buffer)
e := gob.NewEncoder(p)
e.Encode(test)
ers := ioutil.WriteFile("test.gob", p.Bytes(), 0600)
if ers != nil {
    panic(ers)
}

现在我想将test.gob添加到一个函数中。根据我看到的,test.gob的源代码如下:^H^L^@^Ehello

var test string

var b bytes.Buffer

b = byte("^H^L^@^Ehello")

de := gob.NewDecoder(b.Bytes())

er := de.Decode(&test)
if er != nil {
    fmt.Printf("cannot decode")
    panic(er)
}

fmt.Fprintf(w, test)
英文:

I would like to know if it's possible to have gob encoded data directly in the source code (e.g. in a function). The reason is to increase performance by not having to access the disk to get the gob file. I'm aware of memcached, redis and friends. i don't need TTL or any other fancy feature. Just maps in memory. The data would be encoded and dumped in the source code in a 'setup'/build process so that at runtime it would only need to 'decode' it.

The go application would basically serve as a small read-only, embedded database. I can do this using json (basically declare a var with the raw json) but I guess there would be a performance penalty so I'm wondering if it's possible with gob.

I've tried different things but I can't make make it work because basically I don't know how to define the gob var (byte, [bytes] ?? ) and the decoder seems to expect an io.Reader so before spending the whole day on this I've decided to ask you SO fellas at least if it's possible to do.

Miserable attempt:

var test string
test = "hello"

p := new(bytes.Buffer)
e := gob.NewEncoder(p)
e.Encode(test)
ers := ioutil.WriteFile("test.gob", p.Bytes(), 0600)
if ers != nil {
	panic(ers)
}

Now I would like to take test.gob and add it in a function. As I can see, the source of test.gob reads like ^H^L^@^Ehello

var test string

var b bytes.Buffer

b = byte("^H^L^@^Ehello")

de := gob.NewDecoder(b.Bytes())

er := de.Decode(&test)
if er != nil {
	fmt.Printf("cannot decode")
	panic(er)
}

fmt.Fprintf(w, test)

答案1

得分: 5

将数据存储在字节切片中。这是原始数据,你可以从文件中读取它。

你 gob 文件中的字符串不是 "^H^L^@^Ehello"!这是你的编辑器显示非可打印字符的方式。

b := []byte("\b\f\x00\x05hello")
// 这不是 hello 的字符串表示,
// 你需要一个 []byte,而不是 byte。
// 它应该是这样的

de := gob.NewDecoder(b)
// b.Bytes() 返回一个 []byte,你想要读取的是缓冲区本身。

这里有一个可工作的示例:http://play.golang.org/p/6pvt2ctwUq

func main() {
    buff := &bytes.Buffer{}
    enc := gob.NewEncoder(buff)
    enc.Encode("hello")

    fmt.Printf("Encoded: %q\n", buff.Bytes())

    // 现在,如果你想直接在源代码中使用它
    encoded := []byte("\b\f\x00\x05hello")
    // 或 []byte{0x8, 0xc, 0x0, 0x5, 0x68, 0x65, 0x6c, 0x6c, 0x6f}

    de := gob.NewDecoder(bytes.NewReader(encoded))

    var test string
    er := de.Decode(&test)
    if er != nil {
        fmt.Println("cannot decode", er)
        return
    }

    fmt.Println("Decoded:", test)
}
英文:

Store the data in a byte slice. It's raw data, and that's how you would read it in from a file.

The string in your gob file is not "^H^L^@^Ehello"! That's how your editor is displaying the non-printable characters.

b = byte("^H^L^@^Ehello")
// This isn't the string equivalent of hello, 
// and you want a []byte, not byte. 
// It should look like 

b = []byte("\b\f\x00\x05hello")
// However, you already declared b as bytes.Buffer, 
// so this assignment isn't valid anyway.


de := gob.NewDecoder(b.Bytes())
// b.Bytes() returns a []byte, you want to read the buffer itself.

Here's a working example http://play.golang.org/p/6pvt2ctwUq

func main() {
	buff := &bytes.Buffer{}
	enc := gob.NewEncoder(buff)
	enc.Encode("hello")

	fmt.Printf("Encoded: %q\n", buff.Bytes())

	// now if you wanted it directly in your source
	encoded := []byte("\b\f\x00\x05hello")
	// or []byte{0x8, 0xc, 0x0, 0x5, 0x68, 0x65, 0x6c, 0x6c, 0x6f}

	de := gob.NewDecoder(bytes.NewReader(encoded))

	var test string
	er := de.Decode(&test)
	if er != nil {
		fmt.Println("cannot decode", er)
		return
	}

	fmt.Println("Decoded:", test)
}

答案2

得分: 1

例如,

package main

import (
    "bytes"
    "encoding/gob"
    "fmt"
    "io"
)

func writeGOB(data []byte) (io.Reader, error) {
    buf := new(bytes.Buffer)
    err := gob.NewEncoder(buf).Encode(data)
    return buf, err
}

func readGOB(r io.Reader) ([]byte, error) {
    var data []byte
    err := gob.NewDecoder(r).Decode(&data)
    return data, err
}

func main() {
    var in = []byte("hello")
    fmt.Println(string(in))
    r, err := writeGOB(in)
    if err != nil {
        fmt.Println(err)
        return
    }
    out, err := readGOB(r)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(out))
}

输出:

hello
hello
英文:

For example,

package main

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"io"
)

func writeGOB(data []byte) (io.Reader, error) {
	buf := new(bytes.Buffer)
	err := gob.NewEncoder(buf).Encode(data)
	return buf, err
}

func readGOB(r io.Reader) ([]byte, error) {
	var data []byte
	err := gob.NewDecoder(r).Decode(&data)
	return data, err
}

func main() {
	var in = []byte("hello")
	fmt.Println(string(in))
	r, err := writeGOB(in)
	if err != nil {
		fmt.Println(err)
		return
	}
	out, err := readGOB(r)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(out))
}

Output:

hello
hello

huangapple
  • 本文由 发表于 2014年3月8日 21:05:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/22269700.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定