如何优雅或高效地将一个map写入http.ResponseWriter。

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

How to elegantly or efficiently write a map to a http.ResponseWriter

问题

我在想如何以最优雅的方式将一个键值对表单编码映射写入http.ResponseWriter。

Respond(kv map[string]string) {
  for key, value := range kv {
    fmt.Fprintf(a.w, "%s:%s\n", key, value)
  }  
}

我必须遵循这种键值对格式:

键值对表单编码

键值对表单中的消息是一系列行。每行以一个键开始,后跟一个冒号,然后是与该键关联的值。行以单个换行符(UCS代码点10,“\n”)终止。键或值不能包含换行符,键也不能包含冒号。

在冒号或换行符之前或之后不能添加其他字符,包括空格。消息必须以UTF-8编码以生成字节字符串。

我考虑过使用encoding/csv,但那不是有点过度吗?

编辑: 我目前想到的解决方案。(感谢所有提供的答案)

http://godoc.org/github.com/kugutsumen/encoding/keyvalue

https://github.com/kugutsumen/encoding/tree/master/keyvalue

英文:

I was wondering what would be the most elegant way to write a Key Value Form
encoded map to a http.ResponseWriter.

Respond(kv map[string]string) {
  for key, value := range kv {
    fmt.Fprintf(a.w, "%s:%s\n", key, value)
  }  
}

I have to follow this Key-Value format:

> Key-Value Form Encoding
>
> A message in Key-Value form is a sequence of lines. Each line begins
> with a key, followed by a colon, and the value associated with the
> key. The line is terminated by a single newline (UCS codepoint 10,
> "\n"). A key or value MUST NOT contain a newline and a key also MUST
> NOT contain a colon.
>
> Additional characters, including whitespace, MUST NOT be added before
> or after the colon or newline. The message MUST be encoded in UTF-8 to
> produce a byte string.

I thought about using encoding/csv but isn't that a bit overkill?

Edit: What I came up with so far. (Thanks for all the suggested answers)

http://godoc.org/github.com/kugutsumen/encoding/keyvalue

https://github.com/kugutsumen/encoding/tree/master/keyvalue

答案1

得分: 3

标准库提供了对此的支持:请查看 http://godoc.org/net/url#Values

您可以这样做:

f := make(url.Values)
for k, v := range myMap {
    f.Set(k, v)
}
myOutput.WriteString(f.Encode())
英文:

The standard library provides support for this: Look at http://godoc.org/net/url#Values.

You can do something like:

f := make(url.Values)
for k, v := range myMap {
    f.Set(k, v)
}
myOutput.WriteString(f.Encode())

答案2

得分: 2

例如,

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
)

func WriteRespond(w io.Writer, kv map[string]string) error {
	var buf bytes.Buffer
	for k, v := range kv {
		buf.WriteString(k)
		buf.WriteByte(':')
		buf.WriteString(v)
		buf.WriteByte('\n')
		_, err := buf.WriteTo(w)
		if err != nil {
			return err
		}
	}
	return nil
}

func main() {
	kv := map[string]string{
		"k1": "v1",
		"k2": "v2",
	}
	var buf = new(bytes.Buffer)

	w := bufio.NewWriter(buf)
	err := WriteRespond(w, kv)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = w.Flush()
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(buf.Bytes())
	fmt.Println(buf.String())
}

输出:

[107 49 58 118 49 10 107 50 58 118 50 10]
k1:v1
k2:v2
英文:

For example,

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
)

func WriteRespond(w io.Writer, kv map[string]string) error {
	var buf bytes.Buffer
	for k, v := range kv {
		buf.WriteString(k)
		buf.WriteByte(':')
		buf.WriteString(v)
		buf.WriteByte('\n')
		_, err := buf.WriteTo(w)
		if err != nil {
			return err
		}
	}
	return nil
}

func main() {
	kv := map[string]string{
		"k1": "v1",
		"k2": "v2",
	}
	var buf = new(bytes.Buffer)

	w := bufio.NewWriter(buf)
	err := WriteRespond(w, kv)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = w.Flush()
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(buf.Bytes())
	fmt.Println(buf.String())
}

Output:

[107 49 58 118 49 10 107 50 58 118 50 10]
k1:v1
k2:v2

答案3

得分: 1

如果你想要在Go中将字符串写入任何Writer(包括http.ResponseWriter)而不使用fmt包,你可以使用bytes包来读取字符串并将其写入Writer

下面的代码使用bytes.NewBufferStringkeyvalue字符串创建一个Buffer,然后使用WriteTo函数将它们写入http.ResponseWriter

package main

import (
	"bytes"
	"log"
	"net/http"
)

func main() {
	kv := map[string]string{"key1": "val1", "key2": "val2", "key3": "val3", "key4": "val4", "key5": "val5"}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		for key, value := range kv {
			kvw := bytes.NewBufferString(key + ":" + value + "\n")
			if _, err := kvw.WriteTo(w); err != nil {
				log.Fatal("Error: ", err)
			}
		}
	})
	if err := http.ListenAndServe("localhost:8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

将输出:

key1:val1
key2:val2
key3:val3
key4:val4
key5:val5

希望这符合你的要求。

编辑:你也可以使用strings包中的strings.Reader类型和相应的WriteTo函数。

英文:

If you want to write strings to any Writer in Go (including an http.ResponseWriter) without using the fmt package, you can use the bytes package to read the strings and write them to the Writer.

The code below creates a Buffer from the key and value strings using bytes.NewBufferString and then writes them to the http.ResponseWriter using the WriteTo function.

package main

import (
	"bytes"
	"log"
	"net/http"
)

func main() {
	kv := map[string]string{"key1": "val1", "key2": "val2", "key3": "val3", "key4": "val4", "key5": "val5"}
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		for key, value := range kv {
			kvw := bytes.NewBufferString(key + ":" + value + "\n")
			if _, err := kvw.WriteTo(w); err != nil {
				log.Fatal("Error: ", err)
			}
		}
	})
	if err := http.ListenAndServe("localhost:8080", nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

Will output:

>>key1:val1
key2:val2
key3:val3
key4:val4
key5:val5

Hopefully that's close to what you're after.

EDIT: You can also use the strings.Reader Type and the corresponding WriteTo function from the strings package.

huangapple
  • 本文由 发表于 2013年7月16日 08:21:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/17666050.html
匿名

发表评论

匿名网友

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

确定