如何在Flutter中使用http包异步读取API的流式数据
解决方案
你可以通过监听StreamedResponse的stream属性来实时处理分块数据,这个属性是一个Stream<List<int>>,每次API发送数据块时都会触发回调。以下是修改后的完整代码:
import 'package:http/http.dart' as http; import 'dart:convert'; // 用于编码转换 void fetchData() async { final url = Uri.parse('http://my-api-server.com/stream'); final client = http.Client(); try { final request = http.Request('GET', url); final response = await client.send(request); // 监听响应流,处理每个数据块 response.stream.listen( (List<int> chunk) { // 将二进制数据块转换为UTF-8字符串 final chunkString = utf8.decode(chunk); print('收到数据块: $chunkString'); }, onError: (error) { print('流处理错误: $error'); }, onDone: () { print('数据接收完毕'); }, ); } catch (e) { print("请求错误: $e"); } finally { client.close(); } }
关键说明:
- 监听流:
response.stream.listen()是核心方法,onData回调会在每个数据块到达时立即执行。 - 数据转换:API返回的是二进制字节流(
List<int>),需要用utf8.decode()转换为可读字符串,如果你的API使用其他编码(比如gbk),需要替换对应的解码方法。 - 错误处理:
onError回调捕获流处理过程中的异常,onDone在流结束时触发,用于收尾操作。 - 资源管理:
client.close()要放在finally块中,确保无论请求成功或失败都能关闭客户端连接。
如果需要更精细的处理(比如按行解析分块数据),可以使用StreamTransformer对原始流进行转换,例如:
response.stream .transform(utf8.decoder) // 先转成字符串流 .transform(const LineSplitter()) // 按行分割 .listen( (String line) { print('收到一行数据: $line'); }, onError: (error) => print('流处理错误: $error'), onDone: () => print('数据接收完毕'), );
内容的提问来源于stack exchange,提问作者0xdesdenova
相关产品推荐
相关产品推荐

