[Solved] Flutter How to store and access files with AssetBundle


Asked by Serge B on June 23, 2018 (source).

EDIT: This question is about using AssetBundle, while that question (List of files in flutter) was about using Directory. They are different because of different classes. ALSO: I removed one section, that can be similar to previous question.

I don't understand how to use AssetBundle for accessing files...

For example, my assets in pubspec.yaml

- assets/images/
- assets/texts/
  1. AssetBundle has methods: loadString(key, ...) and loadStructuredData(key, ...) - what is a key and how to use this methods?

  2. I need to load data from text files and others files. I know that there is a rootBundle (or DefaultAssetBundle.of(context))... But how to use it to load files?!



Question answered by Richard H (source).

Let's assume that you have an image clock.png in assets/images and a UTF-8 encoded text file distances.json in assets/texts.

The key is really just the path to the asset, so you might load the whole file as a String and decode the json like this:

String distancesText = await rootBundle.loadString('assets/texts/distances.json');
Map distances = json.decode(distancesText);

loadString takes care of the UTF-8 decode for you, and also caches the String for faster access next time.

loadStructuredData takes loadString one step further - it loads the String then calls your provided callback to parse the String and returns the result. This time it caches the decoded result - now saving the reading and decoding step the next time.

Map distances2 = await rootBundle
    .loadStructuredData('assets/texts/distances.json', (String s) async {
  return json.decode(s);

So, this is great for text files; what about binary files? You can read the whole asset as a byte array.

ByteData clockData = await rootBundle.load('assets/images/clock.png');
Uint8List clockBytes = clockData.buffer.asUint8List());

Now you can do whatever you need to do with the binary contents of the file. Note that unlike Strings, binary data isn't cached.

Of course, for a PNG, you would most likely not read it as bytes, but instead load it as an Image Widget with AssetImage. (Also asset images should have multiple resolutions for different DPI devices.) See Assets and Images.

I think that earlier you wanted to obtain a complete list of all the assets available. In some ways this makes no sense. You know which assets you provided at build time, so you could keep the list of assets somewhere yourself - in code or in your own manifest. If you really want to enumerate them at runtime, I think you can load an asset called AssetManifest.json, but this seems to be an implementation detail, so possibly subject to change.