从 golang 中的标准输入读取 json 对象
Read json object from stdin in golang
如何从标准输入读取 json 对象?
我想将一个 json 对象复制并粘贴到标准输入中,读取它并解组它。
这是代码:
var input string
_, err := fmt.Scan(&input)
if err != nil {
fmt.Println(err)
continue
}
var record MedicalRecord
if err := json.Unmarshal([]byte(input), &record); err != nil {
log.Println(err)
continue
}
并将错误打印到控制台。
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 unexpected end of JSON input
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
如果我没记错的话,Go 会一直读取直到找到 '\n' 。我该如何解决这个问题?
当您调用 json.Unmarshal
时,您应该拥有完整的 JSON 对象,否则您只是试图解组一些对解析器没有意义的部分对象。
- 从 stdin 读取到足以容纳整个 JSON 对象的缓冲区。
- 解组 JSON 对象
例如:
package main
import (
"bytes"
"io"
"fmt"
"os"
"bufio"
"encoding/json"
)
func main() {
var buf bytes.Buffer
reader := bufio.NewReader(os.Stdin)
for {
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
buf.WriteString(line)
break // end of the input
} else {
fmt.Println(err.Error())
os.Exit(1) // something bad happened
}
}
buf.WriteString(line)
}
fmt.Printf("valid json? %v\n", json.Valid(buf.Bytes()))
type MedicalRecord struct {
Name string `json:"name"`
Age int `json:"age"`
}
var record MedicalRecord
err := json.Unmarshal(buf.Bytes(), &record)
if err != nil {
fmt.Println(err.Error())
os.Exit(1) // something bad happened
}
fmt.Printf("name: %s, age: %d\n", record.Name, record.Age)
}
使用 *json.Decoder 从 io.Reader 消耗 JSON:
package main
import (
"encoding/json"
"log"
"os"
)
type MedicalRecord struct{}
func main() {
var record MedicalRecord
err := json.NewDecoder(os.Stdin).Decode(&record)
if err != nil {
log.Fatal(err)
}
}
您可以通过重复调用 Decode 来消费多个连续的 JSON 文档:
package main
import (
"encoding/json"
"io"
"log"
"os"
)
type MedicalRecord struct{}
func main() {
var record MedicalRecord
dec := json.NewDecoder(os.Stdin)
for {
err := dec.Decode(&record)
if err == io.EOF {
return
}
if err != nil {
log.Fatal(err)
}
}
}
如何从标准输入读取 json 对象? 我想将一个 json 对象复制并粘贴到标准输入中,读取它并解组它。 这是代码:
var input string
_, err := fmt.Scan(&input)
if err != nil {
fmt.Println(err)
continue
}
var record MedicalRecord
if err := json.Unmarshal([]byte(input), &record); err != nil {
log.Println(err)
continue
}
并将错误打印到控制台。
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 unexpected end of JSON input
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
> 2018/06/26 00:26:32 invalid character ':' after top-level value
> 2018/06/26 00:26:32 invalid character ',' after top-level value
如果我没记错的话,Go 会一直读取直到找到 '\n' 。我该如何解决这个问题?
当您调用 json.Unmarshal
时,您应该拥有完整的 JSON 对象,否则您只是试图解组一些对解析器没有意义的部分对象。
- 从 stdin 读取到足以容纳整个 JSON 对象的缓冲区。
- 解组 JSON 对象
例如:
package main
import (
"bytes"
"io"
"fmt"
"os"
"bufio"
"encoding/json"
)
func main() {
var buf bytes.Buffer
reader := bufio.NewReader(os.Stdin)
for {
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
buf.WriteString(line)
break // end of the input
} else {
fmt.Println(err.Error())
os.Exit(1) // something bad happened
}
}
buf.WriteString(line)
}
fmt.Printf("valid json? %v\n", json.Valid(buf.Bytes()))
type MedicalRecord struct {
Name string `json:"name"`
Age int `json:"age"`
}
var record MedicalRecord
err := json.Unmarshal(buf.Bytes(), &record)
if err != nil {
fmt.Println(err.Error())
os.Exit(1) // something bad happened
}
fmt.Printf("name: %s, age: %d\n", record.Name, record.Age)
}
使用 *json.Decoder 从 io.Reader 消耗 JSON:
package main
import (
"encoding/json"
"log"
"os"
)
type MedicalRecord struct{}
func main() {
var record MedicalRecord
err := json.NewDecoder(os.Stdin).Decode(&record)
if err != nil {
log.Fatal(err)
}
}
您可以通过重复调用 Decode 来消费多个连续的 JSON 文档:
package main
import (
"encoding/json"
"io"
"log"
"os"
)
type MedicalRecord struct{}
func main() {
var record MedicalRecord
dec := json.NewDecoder(os.Stdin)
for {
err := dec.Decode(&record)
if err == io.EOF {
return
}
if err != nil {
log.Fatal(err)
}
}
}