golang 怎么按行读取流式接口返回的数据
在进行网络请求时,有些接口返回的数据是一个逐步生成的流式数据,比如一个长文本,一个日志文件等。在这种情况下,我们可能需要按行读取这个流式数据,而不是一次性将所有数据读取出来。在本文中,我们将介绍如何使用 Golang 实现按行读取流式接口返回的数据。
1. 使用 bufio.Scanner 实现按行读取
Golang 的标准库中提供了 bufio.Scanner
类来实现按行读取数据的功能。我们可以使用 bufio.NewScanner()
函数来创建一个 Scanner
对象,然后通过 Scanner.Scan()
方法来逐行读取数据。
下面是一个简单的示例代码,演示了如何按行读取一个字符串的数据:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "hello\nworld\n"
reader := strings.NewReader(data)
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println("Error:", err)
}
}
在上面的代码中,我们首先创建了一个包含两行文字的字符串,然后使用 strings.NewReader()
函数创建了一个 io.Reader
对象。接着我们创建了一个 bufio.Scanner
对象,并通过 for
循环来逐行读取数据,并输出每一行的内容。最后,我们通过 scanner.Err()
方法检查是否有错误发生。
运行上述代码,我们可以看到如下输出:
hello
world
2. 从网络接口中获取流式数据
除了从字符串中读取数据,我们还可以通过网络请求获取流式数据。下面是一个简单的示例代码,演示了如何从一个 HTTP 接口中获取流式数据,并按行读取:
package main
import (
"bufio"
"fmt"
"net/http"
)
func main() {
resp, err := http.Get("http://example.com/streaming-data")
if err != nil {
panic(err)
}
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println("Error:", err)
}
}
在上面的代码中,我们首先发起一个 HTTP 请求,获取一个包含流式数据的响应对象。然后我们创建了一个 bufio.Scanner
对象,并通过 for
循环来逐行读取数据,并输出每一行的内容。最后,我们通过 scanner.Err()
方法检查是否有错误发生。
3. 自定义按行读取函数
除了使用标准库提供的 bufio.Scanner
实现按行读取外,我们还可以自定义实现按行读取的函数。下面是一个示例代码,演示了如何自定义一个按行读取函数:
package main
import (
"bufio"
"fmt"
"io"
)
func readLine(reader io.Reader) (string, error) {
buf := make([]byte, 0, 4096)
b := make([]byte, 1)
for {
_, err := reader.Read(b)
if err != nil {
return "", err
}
if b[0] == '\n' {
break
}
buf = append(buf, b[0])
}
return string(buf), nil
}
func main() {
data := "hello\nworld\n"
reader := strings.NewReader(data)
for {
line, err := readLine(reader)
if err == io.EOF {
break
} else if err != nil {
panic(err)
}
fmt.Println(line)
}
}
在上面的代码中,我们首先定义了一个 readLine
函数,这个函数接收一个 io.Reader
对象作为参数,然后在循环中逐个字节地读取数据,直到遇到换行符为止。接着我们使用这个函数来从一个包含两行文字的字符串中逐行读取数据,并输出每一行的内容。
结语
在本文中,我们介绍了如何使用 Golang 实现按行读取流式接口返回的数据。我们首先使用标准库提供的 bufio.Scanner
实现了按行读取的功能,然后演示了如何从网络接口中获取流式数据并按行读取,最后我们还自定义实现了一个按行读取函数。