Flutter云存储插件qiniu_flutter_sdk的使用

发布于 1周前 作者 vueper 来自 Flutter

七牛云存储 Flutter SDK qiniu_flutter_sdk

基于七牛云 API 实现,封装了七牛云存储系统的客户端操作。

快速导航

概述

Qiniu-Flutter-SDK 基于七牛云存储官方 API 构建,提供抽象的接口用于快速使用七牛的对象存储功能。注意:token 应从服务端获取。

示例

请查看 Example

快速开始

编辑 pubspec.yaml

dependencies 添加 qiniu-flutter-sdk

dependencies:
  ...
  qiniu_flutter_sdk: ^x.x.x # 替换为需要的版本

导入包

import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';

快速使用

// 创建 storage 对象
final storage = Storage();

// 使用 storage 的 putFile 对象进行文件上传
storage.putFile(File('./file.txt'), 'TOKEN')
  ..then((response) {
    print('上传成功: ${response.key}');
  })
  ..catchError((error) {
    print('上传失败: $error');
  });

监听进度/状态

// 创建 Controller 对象
final putController = PutController();

// 添加整体进度监听
putController.onProgress((double percent) {
  print('任务进度变化:已发送:$percent');
});

// 添加发送进度监听
putController.onSendProgress((double percent) {
  print('已上传进度变化:已发送:$percent');
});

// 添加状态监听
putController.addStatusListener((StorageStatus status) {
  print('状态变化: 当前任务状态:$status');
});

// 使用 storage 的 putFile 对象进行文件上传
storage.putFile(File('./file.txt'), 'TOKEN', PutOptions(
  controller: putController,
));

取消正在上传的任务

// 创建 Controller 对象
final putController = PutController();

// 使用 storage 的 putFile 对象进行文件上传
final uploadTask = storage.putFile(File('./file.txt'), 'TOKEN', PutOptions(
  controller: putController,
));

// 取消当前任务
putController.cancel();

完整示例 Demo

以下是一个完整的 Flutter 示例,包含文件选择、上传进度显示等功能:

import 'dart:convert';
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UploadPage(),
    );
  }
}

class UploadPage extends StatefulWidget {
  @override
  _UploadPageState createState() => _UploadPageState();
}

class _UploadPageState extends State<UploadPage> {
  String? key;
  String? mimeType;
  int partSize = 4;
  String? token;
  final Storage storage = Storage();
  PlatformFile? selectedFile;
  double progressValue = 0.0;
  StorageStatus? statusValue;
  PutController? putController;

  void onSelectedFile(PlatformFile file) {
    setState(() {
      selectedFile = file;
      startUpload();
    });
  }

  void startUpload() {
    putController = PutController();

    putController!.addSendProgressListener((double percent) {
      print('实际发送变化:进度:${percent.toStringAsFixed(4)}');
    });

    putController!.addProgressListener((double percent) {
      setState(() => progressValue = percent);
      print('任务进度变化:进度:${percent.toStringAsFixed(4)}');
    });

    putController!.addStatusListener((StorageStatus status) {
      setState(() => statusValue = status);
      print('状态变化: 当前任务状态:${status.toString()}');
    });

    if (selectedFile == null) {
      printToConsole('请选择文件');
      return;
    }

    final putOptions = PutOptions(
      key: key,
      mimeType: mimeType,
      partSize: partSize,
      controller: putController,
    );

    Future<PutResponse> upload;
    if (kIsWeb) {
      upload = storage.putBytes(
        selectedFile!.bytes!,
        token!,
        options: putOptions,
      );
    } else {
      upload = storage.putFile(
        File(selectedFile!.path!),
        token!,
        options: putOptions,
      );
    }

    upload
      ..then((PutResponse response) {
        print('上传已完成: 原始响应数据: ${jsonEncode(response.rawData)}');
      })
      ..catchError((dynamic error) {
        print('发生错误: $error');
      });
  }

  void printToConsole(String message) {
    debugPrint(message);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('文件上传')),
      body: ListView(
        children: [
          ElevatedButton(
            onPressed: () async {
              FilePickerResult? result = await FilePicker.platform.pickFiles();
              if (result != null) {
                onSelectedFile(result.files.first);
              }
            },
            child: Text('选择文件'),
          ),
          LinearProgressIndicator(value: progressValue),
          Text('上传进度: ${(progressValue * 100).toStringAsFixed(2)}%'),
          if (statusValue == StorageStatus.Request)
            ElevatedButton(
              onPressed: () => putController?.cancel(),
              child: Text('取消上传'),
            ),
        ],
      ),
    );
  }
}

功能列表

  • 单文件上传
  • 分片上传
  • 任务状态
  • 任务进度
  • 上传进度
  • 失败重试

许可证

基于 Apache 2.0 协议发布。


更多关于Flutter云存储插件qiniu_flutter_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter云存储插件qiniu_flutter_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用qiniu_flutter_sdk插件进行云存储操作的示例代码。这个示例包括如何初始化七牛云客户端、上传文件以及处理上传结果的步骤。

首先,确保你已经在pubspec.yaml文件中添加了qiniu_flutter_sdk依赖:

dependencies:
  flutter:
    sdk: flutter
  qiniu_flutter_sdk: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

初始化七牛云客户端

在使用七牛云SDK之前,你需要准备好七牛云的Access Key、Secret Key以及上传所需的Bucket和Zone等信息。这些信息通常可以在你的七牛云管理后台获取。

import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';

void initQiniuClient() async {
  final accessKey = 'your_access_key';
  final secretKey = 'your_secret_key';
  final bucket = 'your_bucket_name';
  final zone = Zone.zone0();  // 根据你的Bucket所在的区域选择合适的Zone

  Auth auth = Auth(accessKey, secretKey);
  Configuration config = Configuration(zone);
  Qiniu qiniu = Qiniu(auth, config);

  // 你可以将qiniu实例保存到一个全局变量中,以便后续使用
  // globalQiniuClient = qiniu;
}

上传文件

下面是一个简单的文件上传示例,它假设你已经选择了一个文件并获取了文件的路径:

import 'package:flutter/material.dart';
import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';
import 'dart:io';

void uploadFile(File file, String key) async {
  // 假设qiniu实例已经通过initQiniuClient初始化
  // final qiniu = globalQiniuClient;

  // 获取上传Token
  String uploadToken = await qiniu.auth.uploadToken(bucket, key, 3600);  // 3600秒过期时间

  // 创建上传管理对象
  FormUploader uploader = FormUploader();

  // 构建上传参数
  PutPolicy putPolicy = PutPolicy();
  putPolicy.scope = bucket;
  putPolicy.setExpires(3600);  // 同样的过期时间

  // 生成上传凭证
  String uploadTokenGenerated = qiniu.auth.uploadToken(putPolicy.toJsonString());

  // 执行上传
  try {
    HttpResponse response = await uploader.put(
      file,
      key,
      uploadTokenGenerated,
      null,
      null
    );

    // 处理上传结果
    if (response.statusCode == 200) {
      // 上传成功,解析响应
      print('Upload successful: ${response.body}');
    } else {
      // 上传失败,处理错误
      print('Upload failed: ${response.statusCode}, ${response.body}');
    }
  } catch (e) {
    // 捕获并处理异常
    print('Error during upload: $e');
  }
}

在UI中触发上传

你可以在Flutter应用的UI中通过按钮点击来触发文件选择和上传操作:

import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:typed_data';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Qiniu Flutter SDK Example'),
        ),
        body: Center(
          child: UploadButton(),
        ),
      ),
    );
  }
}

class UploadButton extends StatefulWidget {
  @override
  _UploadButtonState createState() => _UploadButtonState();
}

class _UploadButtonState extends State<UploadButton> {
  final picker = ImagePicker();

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () async {
        final pickedFile = await picker.pickImage(source: ImageSource.camera);

        if (pickedFile != null) {
          File file = File(pickedFile.path);
          String key = 'example_upload_${DateTime.now().toMillisecondsSinceEpoch()}.jpg';
          await uploadFile(file, key);
        }
      },
      child: Text('Upload File'),
    );
  }
}

注意事项

  1. 权限:确保你的应用有访问存储的权限(Android需要WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE权限,iOS需要NSPhotoLibraryUsageDescriptionNSCameraUsageDescription等权限)。

  2. 依赖版本:请确保你使用的是最新版本的qiniu_flutter_sdk,并且与你的Flutter SDK版本兼容。

  3. 错误处理:在生产环境中,请添加更详细的错误处理和用户反馈机制。

  4. 网络请求:上传操作是网络请求,请确保在网络不佳时添加重试机制或友好的用户提示。

通过上述代码,你应该能够在Flutter应用中实现基本的七牛云文件上传功能。

回到顶部