简体   繁体   中英

How to Write or save Large files in memory in flutter

I'm currently facing an issue, where I'm trying to Save a large video file (586 Mb). I'm able to download the entire file but, when I try to write this file to memory, I get an Error of “Out of memory”. It works for smaller video files like (80mb, 100 mb) but fails for the large files. I'm attaching the code snippet for reference.

Future download() async {
var request = http.Request('GET', Uri.parse(url!));
var response = httpClient.send(request).timeout(Duration(seconds: 3));

var chunks = <List<int>>[];
var downloaded = 0;
try{
  response.asStream().listen((http.StreamedResponse r) {
    if(r.statusCode==HttpStatus.ok){
      r.stream.listen((List<int> chunk) {
        // Display percentage of completion
        chunks.add(chunk);
        downloaded += chunk.length;
        downloadingCallBack(downloaded / r.contentLength! * 100,filesize(downloaded),filesize(r.contentLength));
      }, onDone: () async {
        // Display percentage of completion
        print('downloadPercentage: ${downloaded / r.contentLength! * 100}');
        // Save the file
        try{
          var file =  File('$dirPath/$fileName');
          //The Uint8List below throws the error "Out of memory and I'm not able to write the file to memory" 
         ***Error Here ==>*** final bytes = Uint8List(r.contentLength!); //Code fails here, (r.contentLength is 586900112 bytes)
          var offset = 0;
          for (var chunk in chunks) {
            bytes.setRange(offset, offset + chunk.length, chunk);
            offset += chunk.length;
          }
          await file.writeAsBytes(bytes);
          downloadingDoneBack(true);
          return;
        }catch(fileException){
          rethrow;
        }finally{
          httpClient.close();
        }

      });
    }else{
      downloadingDoneBack(false);
    }

  });
}catch(e){
  downloadingDoneBack(false);
}finally{
  httpClient.close();
}

}

Since it's a large file, I think it would be better to download your file using flutter_downloader plugin which also supports notifications and background mode.

Import and initialize flutter downloader

import 'package:flutter_downloader/flutter_downloader.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // Plugin must be initialized before using
  await FlutterDownloader.initialize(
    debug: true // optional: set to false to disable printing logs to console (default: true)
    ignoreSsl: true // option: set to false to disable working with http links (default: false)
  );

  runApp(const MyApp())
}

Create new download task

final taskId = await FlutterDownloader.enqueue(
  url: 'your download link',
  savedDir: 'the path of directory where you want to save downloaded files',
  showNotification: true, // show download progress in status bar (for Android)
  openFileFromNotification: true, // click on notification to open downloaded file (for Android)
);

Handle isolates

Important note: your UI is rendered in the main isolate, while download events come from a background isolate (in other words, codes in callback are run in the background isolate), so you have to handle the communication between two isolates. For example:

ReceivePort _port = ReceivePort();

@override
void initState() {
  super.initState();

  IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
  _port.listen((dynamic data) {
    String id = data[0];
    DownloadTaskStatus status = data[1];
    int progress = data[2];
    setState((){ });
  });

  FlutterDownloader.registerCallback(downloadCallback);
}

@override
void dispose() {
  IsolateNameServer.removePortNameMapping('downloader_send_port');
  super.dispose();
}

static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
  final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
  send.send([id, status, progress]);
}

Load all download tasks

final tasks = await FlutterDownloader.loadTasks();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM