Flutter使用rootBundle.loadString读取assets文件内容不全问题
- assets目录下存放名为 A# 的文件,调用 rootBundle.loadString 方法读取时,只能获取到部分文件内容,数据存在缺失。
- 文件完整内容如下:
Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet 1.Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet 2.
- 复现代码如下:
final stringA = await rootBundle.loadString("assets/holidays/A#"); print(stringA);
#是URI标准定义的片段分隔符,属于特殊保留字符。rootBundle.loadString内部会将传入的路径参数按URI规则解析,#及之后的所有内容会被识别为资源的片段定位标识,不会被计入实际资源的查找路径,最终加载的资源路径被截断,导致读取到的内容不完整。
对路径中的特殊字符做URL编码即可,#对应的URL编码为%23,直接修改路径参数即可正常读取完整内容:
final stringA = await rootBundle.loadString("assets/holidays/A%23"); print(stringA);
如果路径中可能存在其他特殊字符,也可以调用系统提供的编码方法自动转义,避免手动处理遗漏:
final assetPath = Uri.encodeFull("assets/holidays/A#"); final stringA = await rootBundle.loadString(assetPath); print(stringA);
内容的提问来源于stack exchange,提问作者Nao Kreuzeder

