监听各上传任务或者下载的百分比,并进行缓存本地进行断点续传

2023-08-10  本文已影响0人  xieyinghao
要实现监听上传或下载任务的百分比并进行本地缓存以实现断点续传,你可以使用适当的库和算法来处理任务进度和缓存。以下是一个示例代码:

首先,导入相关库:

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

import 'package:path/path.dart' as path;
import 'package:http/http.dart' as http;
然后,定义一个Task类来表示每个上传或下载任务,并添加一些额外的属性和方法:

dart
class Task {
  final String url;
  final String filename;
  final int totalBytes;
  int bytesDownloaded = 0;

  Task({required this.url, required this.filename, required this.totalBytes});

  Future<void> download() async {
    final file = File(filename);
    final output = file.openWrite();

    final response = await http.get(Uri.parse(url), headers: {'Range': 'bytes=$bytesDownloaded-'});
    response.stream.listen((data) {
      output.add(data);
      bytesDownloaded += data.length;
    }, onDone: () {
      output.close();
    });

    await response.done;
  }

  Future<int> resumeDownload() async {
    final file = File(filename);

    if (file.existsSync()) {
      bytesDownloaded = await file.length();
      return bytesDownloaded;
    }

    return 0;
  }
}
在以上代码中,我们定义了一个Task类,其中包含了任务的URL、文件名和总字节数等属性。download()方法用于执行下载操作,而resumeDownload()方法则用于获取已下载的字节数并返回。

接下来,我们可以创建一个任务列表,并使用StreamController来监听任务的进度变化:

dart
final tasks = <Task>[];
final controller = StreamController<double>();

void addTask(Task task) {
  tasks.add(task);
}

void removeTask(Task task) {
  tasks.remove(task);
}

void updateProgress(double progress) {
  controller.sink.add(progress);
}

void dispose() {
  controller.close();
}
在以上代码中,我们使用tasks列表来存储上传或下载任务,并使用addTask()和removeTask()方法来添加和移除任务。controller是一个StreamController对象,用于发送任务进度的更新。

现在,我们可以编写一个调度器函数来执行任务并更新进度:

dart
Future<void> scheduleTasks() async {
  for (var task in tasks) {
    if (task.bytesDownloaded == task.totalBytes) continue; // 跳过已完成的任务

    await task.download();

    if (task.bytesDownloaded == task.totalBytes) {
      // 任务已完成
    } else {
      // 任务未完成,保存进度以便断点续传
      saveProgress(task);
    }
  }

  dispose(); // 关闭进度监听
}
在上述代码中,我们遍历任务列表,并对每个任务执行下载操作。在下载过程中,我们通过监听响应流并更新bytesDownloaded属性来跟踪进度。如果任务成功完成,我们可以相应地处理它,否则我们将保存进度以便后续断点续传。

最后,我们可以实现一些辅助函数来处理任务的缓存和恢复:

dart
void saveProgress(Task task) {
  final data = '${task.url}|${task.filename}|${task.totalBytes}|${task.bytesDownloaded}';
  final file = File(getProgressFilePath(task));

  file.writeAsStringSync(data);
}

Task? loadProgress(String filename) {
  final file = File(getProgressFilePath(filename));

  if (!file.existsSync()) return null;

  final data = file.readAsStringSync();
  final parts = data.split('|');

  final task = Task(
    url: parts[0],
    filename: parts[1],
    totalBytes: int.parse(parts[2]),
  );

  task.bytesDownloaded = int.parse(parts[3]);
  return task;
}

String getProgressFilePath(String filename) {
  final dir = Directory.systemTemp;
  final basename = path.basename(filename);

  return path.join(dir.path, '$basename.progress');
}
以上代码中,saveProgress()方法用于将任务的进度保存到本地文件中,而loadProgress()方法可以从本地文件中加载并恢复任务的进度。getProgressFilePath()函数用于获取保存进度的文件路径。

通过使用上述函数,你可以在程序启动时检查是否存在任务进度文件,如果存在,则从中恢复任务并继续执行
上一篇 下一篇

猜你喜欢

热点阅读