xen
xen

Reputation: 645

Copy asset from bundle to file system

I'm trying to copy an sqlite database from the root bundle onto the file system in order to use it.

I've tried many different ways but it always ended up writing incorrect amounts of data to disk. The code I'm using looks like this:

Directory appDocDir = await getExternalStorageDirectory();
String path = join(appDocDir.path, "data.db");
bool exists = await new File(path).exists();
if (!exists) {
  var out = new File(path).openWrite();

  var data = await rootBundle.load("assets/data.sqlite");
  var list = data.buffer.asUint8List();
  out.write(list);
  out.close();
}

Upvotes: 11

Views: 4700

Answers (2)

hrsma2i
hrsma2i

Reputation: 4572

I was able to do that by the followings.

ByteData data = await rootBundle.load("data.sqlite");
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

Directory appDocDir = await getApplicationDocumentsDirectory()
String path = join(appDocDir.path, "data.db");
await File(path).writeAsBytes(bytes);

Upvotes: 8

Collin Jackson
Collin Jackson

Reputation: 116838

You can't write the contents of a Uint8List to a File using IOSink.write (which is designed to operate on String arguments). You'll end up writing the UTF-8 encoded representation of the String obtained by calling toString() on your Uint8List, which is probably much larger than the actual contents of the list.

Instead, you can write a Uint8List to the file using IOSink.add.

In the example you've provided, you could also write the entire file at once using new File(path).writeAsBytes(list).

Upvotes: 4

Related Questions