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

以上


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM