Я использую Flutter для загрузки «актива» в File
, чтобы собственное приложение могло получить к нему доступ.
Вот как я загружаю актив:
final dbBytes = await rootBundle.load('assets/file');
Это возвращает экземпляр ByteData
.
Как я могу записать это в экземпляр dart.io.File
?
ByteData
- это абстракция для:
A fixed-length, random-access sequence of bytes that also provides random and unaligned access to the fixed-width integers and floating point numbers represented by those bytes.
Как упоминал Гюнтер в комментариях, вы можете использовать File.writeAsBytes
. Однако для перехода от ByteData
к List<int>
требуется немного работы с API.
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
Future<void> writeToFile(ByteData data, String path) {
final buffer = data.buffer;
return new File(path).writeAsBytes(
buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
У меня также есть подал вопрос, чтобы сделать документацию по Flutter более понятной для этого варианта использования.
Помните, что ByteData
может быть представлением части буфера, поэтому вы можете не захотеть записывать весь буфер. Я обновил пример, чтобы учесть это.
По какой-то причине ваш writeToFile
не работает для> 665 МБ данных. Вы знаете, нужно ли мне устанавливать gradle.properties или подобное? Или у вас есть другое предложение, как писать большие файлы?
@matanlurey Что вы указываете в качестве пути?
для поиска flutter ByteData to List<int>
, затем нашел здесь, но не полностью ответил на мой вопрос:
как конвертировать ByteData
в List<int>
?
после самостоятельного исследования решение:
.cast<int>()
ByteData audioByteData = await rootBundle.load(audioAssetsFullPath);
Uint8List audioUint8List = audioByteData.buffer.asUint8List(audioByteData.offsetInBytes, audioByteData.lengthInBytes);
List<int> audioListInt = audioUint8List.cast<int>();
или 2. используйте .map
ByteData audioByteData = await rootBundle.load(audioAssetsFullPath);
Uint8List audioUint8List = audioByteData.buffer.asUint8List(audioByteData.offsetInBytes, audioByteData.lengthInBytes);
List<int> audioListInt = audioUint8List.map((eachUint8) => eachUint8.toInt()).toList();
Uint8List - это List <int>: абстрактный класс Uint8List реализует List <int>
Спасибо за ваше продуманное решение, но как зашифровать / расшифровать байтовые данные во флаттере
у вас должен быть установлен пакет path_provider, тогда
Это должно работать:
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
final dbBytes = await rootBundle.load('assets/file'); // <= your ByteData
//=======================
Future<File> writeToFile(ByteData data) async {
final buffer = data.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 new File(filePath).writeAsBytes(
buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
//======================
чтобы получить ваш файл:
var file;
try {
file = await writeToFile(dbBytes); // <= returns File
} catch(e) {
// catch errors here
}
Надеюсь это поможет, Спасибо.
Для тех, кто хочет писать байты (также известные как Uint8List) вместо ByteData, обратите внимание, что ByteData - это оболочка для Uint8List.
Из /runtime/lib/typed_data.patch:
@patch
class ByteData implements TypedData {
@patch
@pragma("vm:entry-point")
factory ByteData(int length) {
final list = new Uint8List(length) as _TypedList;
_rangeCheck(list.lengthInBytes, 0, length);
return new _ByteDataView(list, 0, length);
}
@patch
class Uint8List {
@patch
@pragma("vm:exact-result-type", _Uint8List)
factory Uint8List(int length) native "TypedData_Uint8Array_new";
}
Если вы используете последний тип, вы можете использовать ответ, предоставленный Рами, и изменить возвращаемый результат следующим образом:
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
Future<File> writeToFile(Uint8List data) async {
(...)
return new File(filePath).writeAsBytes(data);
}
Ах, круто. Я закончил тем, что сделал
destinationFile.writeAsBytes(dbBytes.buffer.asUint8List());
(в отладчике я увидел, чтоdbBytes
содержитUint8List
). Полагаю, это то же самое, что вы предложили, или один из них эффективнее другого?