我正在写一个dart 包(不是dart ).我已经将一些位图图像作为公共assets资源 ,例如lib/assets/empty.png
.当此软件包作为最终用户的命令行应用程序运行时,如何获取用户系统上这些assets资源 的文件路径?
用例:我的Dart包调用FFMPEG,我需要告诉FFMPEG在使用我的包的系统上从哪里找到这些assets资源 文件.例如,对FFMPEG的调用可能如下所示:
ffmpeg -i "path/to/lib/assets/empty.png" ...
我正在写一个dart 包(不是dart ).我已经将一些位图图像作为公共assets资源 ,例如lib/assets/empty.png
.当此软件包作为最终用户的命令行应用程序运行时,如何获取用户系统上这些assets资源 的文件路径?
用例:我的Dart包调用FFMPEG,我需要告诉FFMPEG在使用我的包的系统上从哪里找到这些assets资源 文件.例如,对FFMPEG的调用可能如下所示:
ffmpeg -i "path/to/lib/assets/empty.png" ...
访问Dart包的assets资源 有两种方式:
dart
工具运行Dart CLI应用程序并访问依赖项的assets资源 ,或这两种情况之间的区别在于,当您使用dart
工具运行CLI应用程序时,您的所有依赖项都可以作为 struct 化包在系统的本地缓存中使用.然而,当您运行一个可执行文件时,所有相关的代码都被编译成一个二进制文件,这意味着您在运行时不再有权访问依赖项的包,您只能访问依赖项的摇动树的编译代码.
dart
以下代码将包assets资源 URI解析为文件系统路径.
final packageUri = Uri.parse('package:your_package/your/asset/path/some_file.whatever');
final future = Isolate.resolvePackageUri(packageUri);
// waitFor is strongly discouraged in general, but it is accepted as the
// only reasonable way to load package assets outside of Flutter.
// ignore: deprecated_member_use
final absoluteUri = waitFor(future, timeout: const Duration(seconds: 5));
final file = File.fromUri(absoluteUri);
if (file.existsSync()) {
return file.path;
}
此解析代码改编自Tim Sneath的winmd
软件包:https://github.com/timsneath/winmd/blob/main/lib/src/metadatastore.dart#L84-L106
将客户端应用程序编译为可执行文件时,该客户端应用程序无法访问与依赖包一起存储的任何assets资源 文件.然而,有一种变通方法可能对某些人有效(它对我有效).您可以在包中的Dart代码中存储assets资源 的Base64编码版本.
首先,将每个assets资源 编码为Base64字符串,并将这些字符串存储在Dart代码中的某个位置.
const myAsset = "iVBORw0KGgoAAA....kJggg==";
然后,在运行时,将字符串解码回字节,然后将这些字节写入本地文件系统上的新文件.以下是我在 case 中使用的方法:
/// Writes this asset to a new file on the host's file system.
///
/// The file is written to [destinationDirectory], or the current
/// working directory, if no destination is provided.
String inflateToLocalFile([Directory? destinationDirectory]) {
final directory = destinationDirectory ?? Directory.current;
final file = File(directory.path + Platform.pathSeparator + fileName);
file.createSync(recursive: true);
final decodedBytes = base64Decode(base64encoded);
file.writeAsBytesSync(decodedBytes);
return file.path;
}
@passsy人建议采用这种方法