In flutter, rootBundle.load()
gives me a ByteData
object.
What exactly is a ByteData
object in dart? Can It be used to read files asynchronously?
I don't really understand the motive behind this.
Why not just give me a good ol' File
object, or better yet the full path of the asset?
In my case, I want to read bytes from an asset file asynchronously, byte by byte and write to a new file. (to build an XOR decryption thingy that doesn't hang up the UI)
This is the best I could do, and it miserably hangs up the UI.
loadEncryptedPdf(fileName, secretKey, cacheDir) async {
final lenSecretKey = secretKey.length;
final encryptedByteData = await rootBundle.load('assets/$fileName');
final outputFilePath = cacheDir + '/' + fileName;
final outputFile = File(outputFilePath);
if (!await outputFile.exists()) {
Stream decrypter() async* {
// read bits from encryptedByteData, and stream the xor inverted bits
for (var index = 0; index < encryptedByteData.lengthInBytes; index++)
yield encryptedByteData.getUint8(index) ^
secretKey.codeUnitAt(index % lenSecretKey);
print('done!');
}
print('decrypting $fileName using $secretKey ..');
await outputFile.openWrite(encoding: AsciiCodec()).addStream(decrypter());
print('finished');
}
return outputFilePath;
}
In Dart a ByteData
is similar to a Java ByteBuffer
. It wraps a byte array, providing getter and setter functions for 1, 2 and 4 byte integers (both endians).
Since you want to manipulate bytes it's easiest to just work on the underlying byte array (a Dart Uint8List
). RootBundle.load()
will have already read the whole asset into memory, so change it in memory and write it out.
Future<String> loadEncryptedPdf(
String fileName, String secretKey, String cacheDir) async {
final lenSecretKey = secretKey.length;
final encryptedByteData = await rootBundle.load('assets/$fileName');
String path = cacheDir + '/' + fileName;
final outputFile = File(path);
if (!await outputFile.exists()) {
print('decrypting $fileName using $secretKey ..');
Uint8List bytes = encryptedByteData.buffer.asUint8List();
for (int i = 0; i < bytes.length; i++) {
bytes[i] ^= secretKey.codeUnitAt(i % lenSecretKey);
}
await outputFile.writeAsBytes(bytes);
print('finished');
}
return path;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With