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

以上

dart 大文件读取的更多相关文章

  1. linux大文件读取

    在生产环境中有时候可能会遇到大文件的读取问题,但是大文件读取如果按照一般的手法.如cat这种都是对io的一个挑战,如果io扛得住还好,如果扛不住 造成的后果,如服务器内存奔溃,日志损坏 方法一: se ...

  2. python大文件读取

    python大文件读取 https://stackoverflow.com/questions/8009882/how-to-read-a-large-file-line-by-line-in-pyt ...

  3. TCP协议传输大文件读取时候的问题

    TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...

  4. Java解决大文件读取的内存问题以及文件流的比较

    Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...

  5. PHP大文件读取操作

    简单的文件读取,一般我们会使用 file_get_contents() 这类方式来直接获取文件的内容.不过这种函数有个严重的问题是它会把文件一次性地加载到内存中,也就是说,它会受到内存的限制.因此,加 ...

  6. 大文件读取方法(C#)

    之前都是用StreamReader.ReadLine方法逐行读取文件,自从.NET4有了File.ReadLines这一利器,就再也不用为大文件发愁了. File.ReadLines在整个文件读取到内 ...

  7. C基础 大文件读取通过标准库

    引言 - 问题的构建 C大部分读取文件的时候采用fgetc, 最近在使用过程中发现性能不是很理想.都懂得fgetc每次只能读取一个字符, IO操作太频繁. 所以性能低. 本文希望通过标准库函数frea ...

  8. php 大文件读取

    当你需要处理一个5G的文件里面的数据时,你会怎么做,将文件里面的内容全部读取到一个数组里面去? 显然这种做法对小文件是没有问题的,但是对于大文件还是不行的 这时就需要用到  yield 了 ,注意这是 ...

  9. C#大文件读取和查询--内存映射

    笔者最近需要快速查询日志文件,文件大小在4G以上. 需求如下: 1.读取4G左右大小的文件中的指定行,程序运行占用内存不超过500M. 2.希望查询1G以内容,能控制在20s左右. 刚开始觉得这个应该 ...

随机推荐

  1. 【redis】redis基础命令学习集合

    写在前面 Redis是一个高速的内存数据库,它的应用十分广泛,可以说是服务端必学必精的东西.然而,学以致用,无用则无为.学了的东西必须反复的去用,去实践,方能有真知.这篇文章记录了我在redis学习过 ...

  2. javascript导出csv文件(excel)

    这里贴出JavaScript导出csv文件(excel)的代码. /** * 导出excel * @param {Object} title 标题列key-val * @param {Object} ...

  3. Spring-boot:多模块打包

    <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot ...

  4. 调度系统Airflow1.10.4调研与介绍和docker安装

    Airflow1.10.4介绍与安装 现在是9102年,8月中旬.airflow当前版本是1.10.4. 随着公司调度任务增大,原有的,基于crontab和mysql的任务调度方案已经不太合适了,需要 ...

  5. 基于python的mysql复制工具

    一简介 python-mysql-replication 是由python实现的 MySQL复制协议工具,我们可以用它来解析binlog 获取日志的insert,update,delete等事件 ,并 ...

  6. caffe学习网站

    1.http://www.cnblogs.com/denny402/tag/caffe/

  7. (五十)c#Winform自定义控件-滑块

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  8. python 34 多进程(二)

    目录 1. 互斥锁 2. 进程之间的通信 2.1 基于文件的通信 2.2 基于队列的通信 1. 互斥锁 ​ 当多个进程抢占同一数据时,将数据加锁,使进程按串行的方式去获取数据,先到先得,保证了公平.数 ...

  9. CentOS -- Zookeeper installation and configure

    1 JDK 1.8 must installed first 2 Get Zookeeper package wget https://archive.apache.org/dist/zookeepe ...

  10. android下JNI开发

    android下JNI开发 what 什么是JNI JNI java native interface native本地 java本地接口 通过JNI可以实现java和本地代码之间相互调用 jni可以 ...