dart 大文件讀取

dart 中不可避免會出現文件讀取的狀況, 甚至是很大的文件, 好比 200M 的文件git

若是一次性讀入內存,雖然也行得通, 可是若是在 flutter 中開啓個 200M 大小的字節數組, 一不當心可能就 crash 了, 這時候就須要使用大文件讀取的方案github

讀取文件

核心方法:數組

file.openRead();

這個方法能夠指定開始和結束的座標, 並開啓一個 streambash

stream 回調信息是 List<int>,單次最大讀取 65536 個字節async

示例

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 在這裏ui

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 解碼後查看寬高要高的多this

項目地址: https://github.com/CaiJingLong/dart_image_size_gettercode

好比判斷一個文件是否是 jpeg 格式, 須要判斷開頭兩個字節和結尾兩個字節是否是 0xFF 0xD9 開頭, 0xFF 0xD8 結尾blog

原始代碼是這樣的, 很不清晰, 也比較難以閱讀:
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

以上

相關文章
相關標籤/搜索