【问题标题】:Dart - HTTPClient download file to stringDart - HTTPClient 下载文件到字符串
【发布时间】:2021-04-08 10:24:19
【问题描述】:

在我目前正在开发的 Flutter/Dart 应用程序中,需要从我的服务器下载大文件。但是,我需要做的不是将文件存储在本地存储中,而是解析其内容并一次性使用它。我认为实现这一点的最佳方法是实现我自己的StreamConsumer 并覆盖相关方法。这是我到目前为止所做的事情

import 'dart:io';
import 'dart:async';

class Accumulator extends StreamConsumer<List<int>>
{
 String text = '';

 @override
  Future<void> addStream(Stream<List<int>> s) async
  {
   print('Adding'); 
   //print(s.length); 
   return; 
  }

 @override 
 Future<dynamic> close() async
 {
  print('closed'); 
  return Future.value(text);
 }
}

Future<String> fileFetch() async
{
 String url = 'https://file.io/bse4moAYc7gW'; 
 final HttpClientRequest request = await HttpClient().getUrl(Uri.parse(url));
 final HttpClientResponse response = await request.close();
 return await response.pipe(Accumulator());
}

Future<void> simpleFetch() async
{
 String url = 'https://file.io/bse4moAYc7gW'; 
 final HttpClientRequest request = await HttpClient().getUrl(Uri.parse(url));
 final HttpClientResponse response = await request.close();
 await response.pipe(File('sample.txt').openWrite());
 print('Simple done!!');  
}

void main() async 
{
 print('Starting'); 
 await simpleFetch(); 
 String text = await fileFetch();
 print('Finished! $text');
}

当我在 VSCode 中运行时,这是我得到的输出

Starting
Simple done!! //the contents of the file at https://file.io/bse4moAYc7gW are duly saved in the file 
sample.txt
Adding //clearly addStream is being called
Instance of 'Future<int>' //I had expected to see the length of the available data here
closed //close is clearly being called BUT
Finished! //back in main()

我对这里潜在问题的理解仍然相当有限。我的期望

  1. 原以为我会用addStream来积累正在下载的内容,直到
  2. 没有更多要下载的内容,此时将调用 close 并且程序将显示 exited

为什么addStream 显示instance of... 而不是可用内容的长度? 尽管 VSCode 调试控制台确实显示 exited,但这种情况会在显示 closed 几秒钟后发生。我认为这可能是不得不打电话给super.close() 的问题,但不是这样。我在这里做错了什么?

【问题讨论】:

    标签: file dart asynchronous download httpclient


    【解决方案1】:

    我本来打算删除这个问题,但为了让其他尝试做类似事情的人受益,我决定把它留在这里并给出答案。

    要注意的关键点是对Accumulator.addStream 的调用就是这样做的——它提供了一个流到listened,没有要读取的实际数据。你接下来要做的是这个

    void whenData(List<int> data)
    {
     //you will typically get a sequence of one or more bytes here.
     for(int value in data)
     {
      //accumulate the incoming data here
     } 
     return;
    } 
    
    function void whenDone()
    {
     //now that you have all the file data *accumulated* do what you like with it
    } 
    
    @override
    Future<void> addStream(Stream<List<int>> s) async
    {
     s.listen(whenData,onDone:whenDone);
     //you can optionally ahandler for `onError`
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-15
      • 1970-01-01
      • 2015-01-16
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多