Flutter笔记:关于Flutter中的大文件上传(上)

news2024/11/26 15:35:14
Flutter笔记
关于Flutter中的大文件上传(上)
大文件上传背景与 Flutter 端实现文件分片传输

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/134302751


本系列上下两篇文章,包括 Flutter 端和 Django 端(后端)两个部分,讨论在 Flutter 端如何处理大文件,以及在 Django 端如何接收。


1. 概述

1.1 大文件上传的应用场景

在Flutter应用中,大文件上传的场景非常常见。例如,用户可能需要上传高清照片、视频或其他大型媒体文件。在企业应用中,用户可能需要上传大量的数据文件或报告。本文的主题是在Flutter应用中实现大文件上传。我们将探讨大文件上传的常见问题,介绍一些有效的上传策略,并提供实现这些策略的Flutter代码示例。我们的目标是帮助读者理解如何在Flutter应用中有效地上传大文件。

1.2 大文件上传的挑战

大文件上传面临许多挑战。首先,网络不稳定可能导致上传失败或速度慢。其次,由于文件大小,上传可能需要很长时间,而上传进度可能不明确,导致用户体验不佳。此外,如果应用在上传过程中崩溃或被关闭,可能需要从头开始上传,这会浪费大量时间和带宽。

1.3 整体上传局限性与优化策略

传统的文件上传方法通常是将整个文件作为一个请求体发送到服务器。然而,这种方法对大文件来说并不理想。由于网络不稳定,大文件有更大的可能性在上传过程中失败。此外,如果应用在上传过程中崩溃或被关闭,可能需要从头开始上传。

为了解决这些问题,我们可以采用一些策略来优化大文件的上传。

1.3.1 分块上传

例如,我们可以使用分块上传,将文件分成多个小块,然后分别上传。这样,即使某个块上传失败,也只需要重新上传该块,而不是整个文件。

1.3.2 断点续传

另一种策略是断点续传,它允许我们在上传被中断后从中断点继续上传,而不是从头开始。这两种策略各有优缺点。分块上传可以提高上传的成功率,但可能需要更复杂的服务器支持。断点续传可以节省带宽,但需要服务器支持范围请求,并且需要在客户端保存上传的进度。

2. 在Flutter中实现大文件上传前的准备

在这一章节中,我们将详细介绍如何在Flutter中实现大文件上传。我们将通过以下步骤来实现这个过程:获取权限、选择文件、分块、上传和处理错误。

2.1 获取权限

在用户选择文件之前,我们需要确保应用有读取文件的权限。我们可以使用permission_handler插件来请求权限。首先,需要在pubspec.yaml文件中添加permission_handler依赖以获取权限。

dependencies:
  permission_handler: 替换你安装的版本号

或者直接在项目中运行下面的命令安装最新版:

flutter pub add permission_handler

然后,我们可以使用Permission类的request方法来请求权限:

import 'package:permission_handler/permission_handler.dart';

void requestPermission() async {
  var status = await Permission.storage.status;
  if (!status.isGranted) {
    status = await Permission.storage.request();
  }
}

2.2 文件选择

在获取了权限后,我们可以使用file_picker插件来选择文件。首先,需要在pubspec.yaml文件中添加依赖:

dependencies:
  file_picker: 替换你安装的版本号

或者直接在项目中运行下面的命令安装最新版:

flutter pub add file_picker

然后,可以使用FilePicker的getFiles方法来选择文件:

import 'package:file_picker/file_picker.dart';

void pickFile() async {
  FilePickerResult? result = await FilePicker.platform.pickFiles();

  if(result != null) {
    PlatformFile file = result.files.first;
    print(file.name);
    print(file.bytes);
    print(file.size);
    print(file.extension);
    print(file.path);
  } else {
    // User canceled the picker
  }
}

3. 文件的切片

3.1 基本思路

在选择了文件后,我们需要将文件分块。分块的目的是将大文件切分成多个小块,这样我们可以逐个上传这些小块,而不是一次性上传整个大文件。这种方法有两个优点:

  1. 如果某个块上传失败,我们只需要重新上传该块,而不是整个文件;
  2. 我们可以更精确地追踪上传进度,因为我们可以知道已经上传了多少块和还剩下多少块。

3.2 实现步骤

在Flutter中,我们可以通过以下步骤来实现文件分块:

  1. 首先,我们需要 获取文件的字节数据
    我们可以使用 PlatformFile 对象的 bytes 属性来获取这些数据。这将返回一个 Uint8List 对象,它是一个包含文件所有字节的列表。

  2. 然后,我们需要 创建一个新的列表来存储分块的数据
    我们可以创建一个空的 List<int> 对象来存储这些数据。

  3. 接下来,我们需要 遍历文件的字节数据,并将数据分块
    我们可以使用一个循环来遍历字节数据。在每次迭代中,我们都会取出一块数据,并将这块数据添加到分块数据的列表中。

  4. 最后,返回分块数据的列表。

3.3 示范案例

一个具体的实现代码如下:

List<int> splitFile(PlatformFile file, int chunkSize) {
  List<int> chunks = [];
  List<int> bytes = file.bytes!.toList();
  for (int i = 0; i < bytes.length; i += chunkSize) {
    int end = (i + chunkSize < bytes.length) ? i + chunkSize : bytes.length;
    chunks.add(bytes.sublist(i, end));
  }
  return chunks;
}

其中,chunkSize 参数表示每个块的大小。

bytes.sublist(i, end) 方法用于获取从 iend 的子列表,这就是我们的一个块。

然后,将这个块添加到 chunks 列表中。这个过程会一直重复,直到所有的字节数据都被分块。

4. 切片的上传

在分块后,我们可以逐个上传这些块。在这个过程中,我们需要创建一个 HTTP 请求,将每个块作为请求的一部分,然后发送这个请求到服务器。我们可以使用 http库 来创建和发送 HTTP 请求。

以下是实现这个功能的步骤:

  1. 首先,我们需要创建一个 MultipartRequest 对象。
    这个对象表示一个 multipart/form-data 请求,它可以包含多个文件和其他类型的数据。我们需要指定请求的方法(在这个例子中是 POST )和 URL

  2. 然后,我们需要将块添加到请求中。
    我们可以使用 MultipartFile 类的 fromBytes 方法来创建一个文件对象,然后将这个对象添加到请求的 files 列表中。

  3. 接下来,我们需要发送请求。
    我们可以使用 send 方法来发送请求,这个方法会返回一个 StreamedResponse 对象。

  4. 最后,我们需要检查响应的状态码,以确定上传是否成功。
    如果状态码是 200,那么上传成功;否则,上传失败。

例如:

import 'package:http/http.dart' as http;

void uploadChunk(List<int> chunk, String url) async {
  var request = http.MultipartRequest('POST', Uri.parse(url));
  request.files.add(http.MultipartFile.fromBytes('file', chunk));
  var response = await request.send();
  if (response.statusCode == 200) {
    print('Uploaded!');
  } else {
    print('Failed to upload.');
  }
}

其中:
chunk 参数是我们要上传的块,url 参数是服务器的 URL
MultipartFile.fromBytes 方法的第一个参数是文件的名字,第二个参数是文件的字节数据;
send 方法会异步发送请求,所以我们需要使用 await 关键字来等待它完成。

5. 完整实现

作为Flutter端完整实现我简单写了一下,上传到了 Git Hub并发布在 Pub.dev,地址为:https://pub.dev/packages/slivers_uploader。在该实现中,我将文件选择和上传分开。一个Flutter端示例如下:

import 'package:flutter/material.dart';
import 'package:slivers_uploader/slivers_uploader.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'File Uploader Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final uploader = FileUploader();

  MyHomePage({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('File Uploader Example'),
      ),
      body: Center(
        child: TextButton(
          child: const Text('Upload File'),
          onPressed: () async {
            var file = await uploader.pickFile();
            await file.upload(
              url: 'http://127.0.0.1/upload',
              onSuccess: () {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Upload successful!')),
                );
              },
              onError: () {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Upload failed.')),
                );
              },
            );
          },
        ),
      ),
    );
  }
}

在这里插入图片描述

下一篇文章,我们主要介绍 Django 后端如何实现对应的分块上传的文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1188671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业办理CCRC需要多少费用?

近几年&#xff0c;很多企业都在咨询了解CCRC认证&#xff0c;各企业对于办理CCRC资质认证最在意的一个环节就是办理的费用&#xff0c;也有不少企业都在咨询同邦信息科技的小编费用的问题&#xff0c;那今天同邦信息科技的小编就给大家说一下 先来给大家科普一下CCRC认证&…

浅谈数据中心机房末端配电技术与产品监控选型-安科瑞黄安南

摘要 数据中心机房末端配电的可靠性、稳定性和可维护性直接关系到IT设备的安全供电。数据中心的末端配电技术主要有两种&#xff0c;一种采用列头柜加电缆配电&#xff0c;另一种是智能小母线配电。分别对两种配电技术进行了介绍和探讨&#xff0c;最后对两种配电方式进行了对…

搜款网VVIC商品详情API接口

搜款网VVIC商品详情接口提供了全面的API接口&#xff0c;通过该接口&#xff0c;开发者可以使用商品ID等参数请求API&#xff0c;获取商品的详细信息&#xff0c;如商品标题、描述、价格、库存状态、销售量等。 要使用VVIC商品详情接口&#xff0c;您需要先注册开发者账号并申…

Yarn安装成功但提示 command not found 解决方案

文章目录 查看yarn配置卸载yarn删除注册表清除yarn缓存npm安装yarn安装完成后yarn -v提示command not found&#xff0c;故选择使用命令重新安装命令安装yarn然后打开.bash_profile文件&#xff1a;参考&#xff1a;https://www.python100.com/html/119013.html 最近遇到项目使…

【23-24 秋学期】NNDL 作业7 基于CNN的XO识别

一、用自己的语言解释以下概念 局部感知、权值共享池化&#xff08;子采样、降采样、汇聚&#xff09;。会带来那些好处和坏处&#xff1f;全卷积网络&#xff08;课上讲的这个概念不准确&#xff0c;同学们查资料纠正一下&#xff09;低级特征、中级特征、高级特征多通道。N输…

佳易王会员管理系统软件如何下载,基本功能有哪些

一、佳易王会员管理软件大众版 部分功能简介&#xff1a; 1、会员信息登记 &#xff1a;可以直接使用手机号登记&#xff0c;也可以使用实体卡片&#xff0c;推荐用手机号即可。 2、会员卡类型 &#xff1a;可以自由设置卡的类型&#xff0c;比如&#xff1a;充值卡、计次卡、…

HCIA-单臂路由-VLAN-VLAN间通信-OSPF 小型实验

HCIA-单臂路由-VLAN-VLAN间通信-OSPF 实验拓扑配置步骤第一步 配置二层VLAN第二步 配置VLANIF和IP地址第三步 配置OSPF 配置验证PC1可以ping通PC2 PC3 PC4 实验拓扑 配置步骤 第一步 配置二层VLAN 第二步 配置VLANIF和IP地址 第三步 配置OSPF 第一步 配置二层VLAN SW1 sysna…

一篇简述 Linux 移植与系统启动

1、Linux系统启动与U-Boot 所谓移植就是把程序代码从一种运行环境转移到另一种运行环境。对于内核移植来说&#xff0c;主要是从一种硬件平台转移到另一种硬件平台上运行。 体系结构级别的移植是指在不同体系结构平台上Linux内核的移植&#xff0c;例如&#xff0c;在ARM、MI…

arco-design:列tsx语法,点击弹窗

最近在一个大屏项目中使用到arco-design&#xff0c;版本为2.52.1&#xff1b; 主要代码如下 列表template <template><div class"table_alarm"><!-- row-click"handleRowClick" --><a-tablerow-key"key"size"mini&…

【JavaEESpring】Spring Web MVC⼊⻔

Spring Web MVC 1. 什么是 Spring Web MVC1.1 什么是 MVC ?1.2 是什么 Spring MVC? 2. 学习 Spring MVC2.1 建立连接2.2 请求2.3 响应 3. 相关代码链接 1. 什么是 Spring Web MVC 官⽅对于 Spring MVC 的描述是这样的&#xff1a; 1.1 什么是 MVC ? MVC 是 Model View C…

os_cfg.h、os_cpu.h和ucos_ii.h

目录 文件组织代码研读#ifndef OS_CFG_H#if OS_TASK_STAT_EN > 0u 文件组织 os_cfg.h 用于定义操作系统&#xff08;OS&#xff09;的配置参数&#xff0c;例如任务数量、堆栈大小、时间片大小等。它通常包含了用户可以根据需求进行配置的宏定义。os_cpu.h 用于定义与特定CP…

Wireshark学习 与 TCP/IP协议分析

Wireshark简介和工具应用 如何开始抓包&#xff1f; 打开wireshark&#xff0c;显示如下网络连接。选择你正在使用的&#xff0c;&#xff08;比如我正在使用无线网上网&#xff09;&#xff0c;双击 可以先看下自己的ip地址和网关ip地址&#xff08;看抓包数据时候会用到&…

福州湾107㎡三室两厅两卫,温柔如风的奶油原木风,自由浪漫的灵魂。福州中宅装饰,福州装修

今天要分享的是一套面积107平米的奶油原木风三室两厅的案例。设计师于业主诉求中抽丝剥茧&#xff0c;汲取灵感&#xff0c;以大热的现代风格为主&#xff0c;暖色为主基调&#xff0c;配合原木肌理和巧思的质感细节装饰&#xff0c;最终打造出一种自由与惬意的空间。 01丨业 主…

api-ms-win-crt-runtime-l1-1-0.dll缺失了怎么解决?4个方法快速修复dll文件

在我们使用电脑的过程中&#xff0c;error提示框是我们不希望看到的事情之一。特别是像“api-ms-win-crt-runtime-l1-1-0.dll文件缺失”的错误&#xff0c;很可能会使一个应用程序完全无法运行。这种情况下&#xff0c;你一定感到头大。不过&#xff0c;请你不要担心。首先&…

英伟达发布RAPIDS cuDF框架 pandas在GPU上运行速度快了150倍

11月9日 消息&#xff1a;Nvidia 发布了一款名为 RAPIDS cuDF 的新版本&#xff0c;据称可以将 pandas 运行在 GPU 上&#xff0c;并且性能提升了150倍。pandas 是一款流行的基于 Python 的数据框架库&#xff0c;用于数据处理和分析。它的开源版本由 Wes McKinney 开发和发布&…

通达OA get_datas.php前台sql注入-可获取数据库session登入后台漏洞复现 [附POC]

文章目录 通达OA get_datas.php前台sql注入-可获取数据库session登入后台漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 通达OA get_datas.php前台sql注入-可获取数据库session登入后台漏洞复现…

2023年【A特种设备相关管理(锅炉压力容器压力管道)】考试内容及A特种设备相关管理(锅炉压力容器压力管道)考试技巧

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;考试内容根据新A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;考试大纲要求&#xff0c;安全生产模拟考试一点通将A特种设备相关管理…

python定时任务scheduler根据参数执行

python执行定时任务请参考&#xff1a;python使用apscheduler每隔一段时间自动化运行程序 传入参数时&#xff1a; 使用add_job函数中添加参数&#xff1a;args[参数1, 参数2]....传入参数顺序与对应位置一致 示例程序 import datetime from apscheduler.schedulers.backg…

基于安卓android微信小程序的校园互助平台

项目介绍 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整…