35

Here is my pubspec.yaml:

  assets:
    - assets/mySecertImage.png

Here is how I read back the assets:

  var data = await PlatformAssetBundle().load('assets/mySecertImage.png');

Instead of reading it directly, can I get the file path instead? If it is not possible to do so, it is possible to change the data to become a File object? Thanks.

2
  • Would it solve your problem reading from the bundle and saving it to a real file when starting the app (in the main method)? If so let me know and I'll show you the code to do just that. Commented Sep 16, 2018 at 20:51
  • This code will work perfectly Future<File> getImageFileFromAssets(String path) async { final byteData = await rootBundle.load('assets/$path'); final buffer = byteData.buffer; Directory tempDir = await getTemporaryDirectory(); String tempPath = tempDir.path; var filePath = tempPath + '/file_01.tmp'; // file_01.tmp is dump file, can be anything return File(filePath) .writeAsBytes(buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes)); } Commented Feb 19, 2022 at 16:06

5 Answers 5

29

Have you found a solution ? (I am looking for the same as well).

Here is a workaround that I pursue (out of lack of a better idea)... :

I do:

  • create a new File-path to your Documents-directory (named app.txt in the below code-example)
  • copy the File sitting in your assets folder to this Documents-directory location
  • work with the copied file from now on (where you now have File-path and even Byte-content if needed)

Here is the Dart-code:

import 'package:path/path.dart';

Directory directory = await getApplicationDocumentsDirectory();
var dbPath = join(directory.path, "app.txt");
ByteData data = await rootBundle.load("assets/demo.txt");
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(dbPath).writeAsBytes(bytes);

Some people also work with the getDatabasesPath() instead of getApplicationDocumentsDirectory(). But I figured that on an iOS-Simulator this ends up being the exact same location. (not verified on Android)... So, it would say:

var dbDir = await getDatabasesPath();
var dbPath = join(dbDir, "app.txt");
ByteData data = await rootBundle.load("assets/demo.txt");
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
await File(dbPath).writeAsBytes(bytes);

For an iOS-Simulator: In both above examples, you can find your copied file under the folder:

/Users/username/Library/Developer/CoreSimulator/Devices/AE5C3275-CD65-3537-9B32-53533B97477C/data/Containers/Data/Application/7BE2B2EE-4E45-3783-B4BD-341DA83C43BD/Documents/app.txt

(of course, the UUID's being different in your case...)

And if you want to copy the file only if it does not exist already, you could write:

Directory directory = await getApplicationDocumentsDirectory();
var dbPath = join(directory.path, "app.txt");
if (FileSystemEntity.typeSync(dbPath) == FileSystemEntityType.notFound) {
  ByteData data = await rootBundle.load("assets/demo.txt");
  List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
  await File(dbPath).writeAsBytes(bytes);
}
Sign up to request clarification or add additional context in comments.

4 Comments

What is 'rootBundle' then?
@OliverDixon rootBundle is a Flutter library. import 'package:flutter/services.dart' show rootBundle; See here for more info : flutter.dev/docs/development/ui/assets-and-images
please don't forget to add first the dependency path_provider: ^1.3.0 to pubspec.yaml other the getApplicationDocumentsDirectory() will give you error.
@ArifMustafa How do I express my gratitude for just mentioning that! I saw various articles about this,,but none, not even a google sample for FireStore mentioned that "Do not forget to add depdendency for this". Coming from Native Android I was in an illusion it should be OOB, took me 30mins to figure this out! Thank you!
11

You can not get the file path of an asset file, because assets, that are bundled with your app, are stored inside an archive.

See the "Asset building" section here:

https://flutter.dev/docs/development/ui/assets-and-images#asset-bundling

During a build, Flutter places assets into a special archive called the asset bundle that apps read from at runtime.

Comments

6

I had the same issue but fixed by calling this.

Future<File> getImageFileFromAssets(String path) async {
 final byteData = await rootBundle.load('assets/$path');
 final buffer = byteData.buffer;
 Directory tempDir = await getTemporaryDirectory();
 String tempPath = tempDir.path;
 var filePath =
  tempPath + '/file_01.tmp'; // file_01.tmp is dump file, can be anything
 return File(filePath)
  .writeAsBytes(buffer.asUint8List(byteData.offsetInBytes, 
 byteData.lengthInBytes));
}

Comments

4

An alternative to Harjinder's implementation: It handles the case that the path includes directories and it avoids rewriting the file

  Future<File> _getImageFileFromAssets(String path) async {
    Directory tempDir = await getTemporaryDirectory();
    String tempPath = tempDir.path;
    var filePath = "$tempPath/$path";
    var file = File(filePath);
    if (file.existsSync()) {
      return file;
    } else {
      final byteData = await rootBundle.load('assets/$path');
      final buffer = byteData.buffer;
      await file.create(recursive: true);
      return file
          .writeAsBytes(buffer.asUint8List(byteData.offsetInBytes,
          byteData.lengthInBytes));
    }
  }

Comments

0

Also make sure sometimes is required to specify the path as following: 'packages/$nameOfThePackage/$assetPath' if your assets are in a separate package you might use for splitting the features. nameOfThePackage being the library name of the alternative package you use. assetPath as an example is 'assets/images/'

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.