如何获取Dart包中包含的资源文件路径?

7

我正在编写一个Dart包(非Flutter)。 我已将一些位图图像作为公共资产包含在内,例如lib/assets/empty.png。 当此包作为面向最终用户的命令行应用程序运行时,如何获取用户系统上这些资源的文件路径?

用例:我的Dart包调用FFMPEG,并且我需要告诉FFMPEG在使用我的包的系统上找到这些资产文件的位置。例如,对FFMPEG的调用可能如下所示:

ffmpeg -i "path/to/lib/assets/empty.png" ...
2个回答

5

访问Dart包的资源有两种方式:

  1. 使用dart工具运行Dart CLI应用程序并访问依赖项的资源,或者
  2. 运行可执行CLI应用程序。

这两种情况之间的区别在于,当您使用dart工具运行CLI应用程序时,所有依赖项都作为结构化包在您系统上的本地缓存中可用。但是,当您运行一个可执行文件时,所有相关的代码将被编译成单个二进制文件,这意味着您在运行时不再可以访问您的依赖项的包,您只能访问您的依赖项的摇树优化编译后的代码。

使用dart运行时访问资源

以下代码将把一个包资源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

在可执行文件运行时访问资源

将客户端应用程序编译为可执行文件后,该客户端应用程序无法访问存储在依赖包中的任何资产文件。但是,有一个解决方法可以适用于某些人(对我而言确实有效)。您可以将您的资产的Base64编码版本存储在您的Dart代码中,即在您的包内。

首先,将每个资产编码为Base64字符串,并将这些字符串存储在您的Dart代码的某个地方。

const myAsset = "iVBORw0KGgoAAA....kJggg==";

然后,在运行时将字符串解码回字节,然后将这些字节写入本地文件系统中的新文件。以下是我在我的案例中使用的方法:

/// 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建议的。


0

看一下dcli包。

它有一个“pack”命令,专门设计用来解决这个问题。

它将资产编码为可以在运行时解压缩的dart文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接