2013-07-16 30 views
0

我想知道什麼是最優雅的方式來編寫一個鍵值表 編碼地圖到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編碼爲 產生一個字節字符串。

我想過使用編碼/ csv,但不是有點矯枉過正?

編輯:到目前爲止我想出了。 (感謝所有的建議答案)

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

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

回答

1

如果不想使用fmt包寫在Go字符串任何Writer(包括http.ResponseWriter),你可以使用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.Reader類型和strings包中相應的WriteTo函數。

+0

我沒有使用http.HandleFunc :)我一直在尋找的東西效率比調用fmt.Fprintf問題...... – Kugutsumen

+0

我已經編輯我的答案使用'bytes'包而不是'fmt'包。它可能更接近你想要的。 – Intermernet

+0

你也可以使用'strings'包來實現相同的功能。 – Intermernet

1

例如,

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 
+0

寫入「緩衝​​區」後無需檢查錯誤。 'Buffer'的Write函數總是返回'nil'作爲錯誤。 – Mostafa

+0

@Mostafa:歡迎提出意見。不要改變答案。你的改變是錯誤的。 – peterSO

+0

爲什麼不換?這就是工作原理。刪除總是假的子句會出現什麼問題? – Mostafa

3

標準庫提供這種支持:看http://godoc.org/net/url#Values

你可以這樣做:

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

感謝這是一個很好的提示...我開始通過編寫我的encode()函數基於url.Values的encode(),但不喜歡它使用一個字符串數組作爲值,而Add()方法只是附加到數組,而Get()方法返回數組中的第一個條目。此外,我使用的編碼必須遵循Openid Auth 2.0(4.1.1)。 – Kugutsumen