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 结尾

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

经过修改后是这样的

  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

以上

posted on 2019-09-20 17:16  侍风念影  阅读(...)  评论(... 编辑 收藏

导航

统计