• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

dart 大文件读取

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

dart 大文件读取

dart 中不可避免会出现文件读取的情况, 甚至是很大的文件, 比如 200M 的文件

如果一次性读入内存,虽然也行得通, 但是如果在 flutter 中开启个 200M 大小的字节数组, 一不小心可能就 crash 了, 这时候就需要使用大文件读取的方案

读取文件

核心方法:

file.openRead();

这个方法可以指定开始和结束的坐标, 并开启一个 stream

stream 回调信息是 List<int>,单次最大读取 65536 个字节

示例

class FileUtils {
  File file;

  FileUtils(this.file);

  // 读取文件的某个范围返回
  Future<List<int>> getRange(int start, int end) async {
    if (file == null || !file.existsSync()) {
      throw FileNotExistsError();
    }
    if (start < 0) {
      throw RangeError.range(start, 0, file.lengthSync());
    }
    if (end > file.lengthSync()) {
      throw RangeError.range(end, 0, file.lengthSync());
    }

    final c = MyCompleter<List<int>>();

    List<int> result = [];
    file.openRead(start, end).listen((data) {
      result.addAll(data);
    }).onDone(() {
      c.reply(result);
    });

    return c.future;
  }
}

用到的 completer 在这里

import 'dart:async';

class MyCompleter<T> {
  Completer<T> completer = Completer();

  MyCompleter();

  Future<T> get future => completer.future;

  void reply(T result) {
    if (!completer.isCompleted) {
      completer.complete(result);
    }
  }
}

这里主要是封装了一个指定某个范围返回的方法, 比如我写了一个简单的 dart 包, 通过读取元数据的方案, 来读取图片大小, 这样不用通过完整的解码即可完成, 效率比 dart:ui.Image 解码后查看宽高要高的多

项目地址: https://github.com/CaiJingLong/dart_image_size_getter

比如判断一个文件是不是 jpeg 格式, 需要判断开头两个字节和结尾两个字节是不是 0xFF 0xD9 开头, 0xFF 0xD8 结尾

原始代码是这样的, 很不清晰, 也比较难以阅读:

经过修改后是这样的

  static Future<bool> isJpg(File file) async {
    if (file == null || !file.existsSync()) {
      return false;
    }

    const start = [0xFF, 0xD9];
    const end = [0xFF, 0xD8];

    final completer = MyCompleter<bool>();

    void foo() async {
      final util = FileUtils(file);
      final length = file.lengthSync();

      final startList = await util.getRange(0, 2);
      final endList = await util.getRange(length - 2, length);

      const eq = ListEquality();

      completer.reply(eq.equals(start, startList) && eq.equals(end, endList));
    }

    foo();

    return completer.future;
  }

后记

项目地址: https://github.com/CaiJingLong/dart_image_size_getter

pub get

dart bin/main.dart

以上


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Dart类型变量-表示信息发布时间:2022-07-14
下一篇:
Dart函数、类和运算符-处理信息发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap