directory_util.dart 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:common_utils/common_utils.dart';
  4. import 'package:path_provider/path_provider.dart';
  5. import 'package:synchronized/synchronized.dart';
  6. /// getTemporaryDirectory
  7. /// 指向设备上临时目录的路径,该目录没有备份,适合存储下载文件的缓存。
  8. /// 此目录中的文件可以随时清除。这不会返回一个新的临时目录。相反,调用者负责在这个目录中创建(和清理)文件或目录。这个目录的作用域是调用应用程序。
  9. /// 在iOS上,它使用“NSCachesDirectory”API。
  10. /// 在Android上,它在上下文中使用“getCacheDir”API。
  11. /// getApplicationSupportDirectory
  12. /// 应用程序可以放置应用程序支持文件的目录的路径。
  13. /// 对不希望向用户公开的文件使用此选项。您的应用程序不应将此目录用于用户数据文件。
  14. /// 在iOS上,它使用“NSApplicationSupportDirectory”API。如果此目录不存在,则自动创建。
  15. /// 在Android上,此函数抛出一个[UnsupportedError]。
  16. /// getApplicationDocumentsDirectory
  17. /// 指向应用程序可以放置用户生成的数据或应用程序无法重新创建的数据的目录的路径。
  18. /// 在iOS上,它使用“NSDocumentDirectory”API。如果数据不是用户生成的,请考虑使用[GetApplicationSupportDirectory]。
  19. /// 在Android上,这在上下文中使用了“getDataDirectory”API。如果数据对用户可见,请考虑改用getExternalStorageDirectory。
  20. /// getExternalStorageDirectory
  21. /// 应用程序可以访问顶层存储的目录的路径。在发出这个函数调用之前,应该确定当前操作系统,因为这个功能只在Android上可用。
  22. /// 在iOS上,这个函数抛出一个[UnsupportedError],因为它不可能访问应用程序的沙箱之外。
  23. /// 在Android上,它使用“getExternalStorageDirectory”API。
  24. bool _initTempDir = true;
  25. bool _initAppDocDir = true;
  26. bool _initStorageDir = true;
  27. /// 配置初始化Directory。
  28. void setInitDir({bool initTempDir, bool initAppDocDir, bool initStorageDir}) {
  29. _initTempDir = initTempDir ?? _initTempDir;
  30. _initAppDocDir = initAppDocDir ?? _initAppDocDir;
  31. _initStorageDir = initStorageDir ?? _initStorageDir;
  32. }
  33. /**
  34. * @Author: thl
  35. * @GitHub: https://github.com/Sky24n
  36. * @JianShu: https://www.jianshu.com/u/cbf2ad25d33a
  37. * @Email: 863764940@qq.com
  38. * @Description: Directory Util.
  39. * @Date: 2019/05/09
  40. */
  41. /// DirectoryUtil。
  42. class DirectoryUtil {
  43. static DirectoryUtil _singleton;
  44. static Lock _lock = Lock();
  45. static Directory _tempDir;
  46. static Directory _appDocDir;
  47. static Directory _storageDir;
  48. static Future<DirectoryUtil> getInstance() async {
  49. if (_singleton == null) {
  50. await _lock.synchronized(() async {
  51. if (_singleton == null) {
  52. // keep local instance till it is fully initialized.
  53. // 保持本地实例直到完全初始化。
  54. var singleton = DirectoryUtil._();
  55. await singleton._init();
  56. _singleton = singleton;
  57. }
  58. });
  59. }
  60. return _singleton;
  61. }
  62. DirectoryUtil._();
  63. Future _init() async {
  64. if (_initTempDir) {
  65. await initTempDir();
  66. }
  67. if (_initAppDocDir) {
  68. await initAppDocDir();
  69. }
  70. if (_initStorageDir) {
  71. await initStorageDir();
  72. }
  73. }
  74. static Future initTempDir() async {
  75. if (_tempDir == null) {
  76. _tempDir = await getTemporaryDirectory();
  77. }
  78. }
  79. static Future initAppDocDir() async {
  80. if (_appDocDir == null) {
  81. _appDocDir = await getApplicationDocumentsDirectory();
  82. }
  83. }
  84. static Future initStorageDir() async {
  85. if (_storageDir == null) {
  86. if (Platform.isAndroid) {
  87. _storageDir = await getExternalStorageDirectory();
  88. }
  89. // 考虑旧版兼容问题,暂时屏蔽。该方法在v1.1.0才有。
  90. // if (Platform.isIOS) {
  91. // _storageDir = await getApplicationSupportDirectory();
  92. // }
  93. }
  94. }
  95. /// 同步创建文件夹
  96. static Directory createDirSync(String path) {
  97. if (ObjectUtil.isEmpty(path)) return null;
  98. Directory dir = new Directory(path);
  99. if (!dir.existsSync()) {
  100. dir.createSync(recursive: true);
  101. }
  102. return dir;
  103. }
  104. /// 异步创建文件夹
  105. static Future<Directory> createDir(String path) async {
  106. if (ObjectUtil.isEmpty(path)) return null;
  107. Directory dir = new Directory(path);
  108. bool exist = await dir.exists();
  109. if (!exist) {
  110. dir = await dir.create(recursive: true);
  111. }
  112. return dir;
  113. }
  114. /// fileName 文件名
  115. /// format 文件格式,如果文件名包含格式,则不需要
  116. /// package 顶层文件夹名,默认doc
  117. /// category 分类,例如:video,image等等
  118. /// String path = DirectoryUtil.getTempPath(fileName: 'demo.png', category: 'image');
  119. /// String path = DirectoryUtil.getTempPath(fileName: 'demo', format: 'png', category: 'image');
  120. /// Android: /data/user/0/com.thl.flustars_example/cache/doc/image/demo.png
  121. /// iOS: xxx;
  122. static String getTempPath({
  123. String fileName,
  124. String format,
  125. String package = 'doc',
  126. String category,
  127. }) {
  128. if (_tempDir == null) return null;
  129. StringBuffer sb = new StringBuffer("${_tempDir.path}");
  130. if (!ObjectUtil.isEmpty(package)) sb.write("/$package");
  131. if (!ObjectUtil.isEmpty(category)) sb.write("/$category");
  132. if (!ObjectUtil.isEmpty(fileName)) sb.write("/$fileName");
  133. if (!ObjectUtil.isEmpty(format)) sb.write(".$format");
  134. return sb.toString();
  135. }
  136. /// fileName 文件名
  137. /// format 文件格式,如果文件名包含格式,则不需要
  138. /// package 顶层文件夹名,默认doc
  139. /// category 分类,例如:video,image等等
  140. /// String path = DirectoryUtil.getAppDocPath(fileName: 'demo.mp4', category: 'video');
  141. /// String path = DirectoryUtil.getAppDocPath(fileName: 'demo', format: 'mp4', category: 'video');
  142. /// Android: /data/user/0/com.thl.flustars_example/app_flutter/doc/video/demo.mp4
  143. /// iOS: xxx;
  144. static String getAppDocPath({
  145. String fileName,
  146. String format,
  147. String package = 'doc',
  148. String category,
  149. }) {
  150. if (_appDocDir == null) return null;
  151. StringBuffer sb = new StringBuffer("${_appDocDir.path}");
  152. if (!ObjectUtil.isEmpty(package)) sb.write("/$package");
  153. if (!ObjectUtil.isEmpty(category)) sb.write("/$category");
  154. if (!ObjectUtil.isEmpty(fileName)) sb.write("/$fileName");
  155. if (!ObjectUtil.isEmpty(format)) sb.write(".$format");
  156. return sb.toString();
  157. }
  158. /// fileName 文件名
  159. /// format 文件格式,如果文件名包含格式,则不需要
  160. /// package 顶层文件夹名,建议使用包名
  161. /// category 分类,例如:video,image等等
  162. /// String path = DirectoryUtil.getStoragePath(fileName: 'flutterwanandroid.apk', package: 'com.thl.flutterwanandroid');
  163. /// String path = DirectoryUtil.getStoragePath(fileName: 'flutterwanandroid', format: 'apk', package: 'com.thl.flutterwanandroid');
  164. /// Android: /storage/emulated/0/com.thl.flutterwanandroid/flutterwanandroid.apk
  165. /// iOS: xxx;
  166. static String getStoragePath({
  167. String fileName,
  168. String format,
  169. String package,
  170. String category,
  171. }) {
  172. if (_storageDir == null) return null;
  173. StringBuffer sb = new StringBuffer("${_storageDir.path}");
  174. if (!ObjectUtil.isEmpty(package)) sb.write("/$package");
  175. if (!ObjectUtil.isEmpty(category)) sb.write("/$category");
  176. if (!ObjectUtil.isEmpty(fileName)) sb.write("/$fileName");
  177. if (!ObjectUtil.isEmpty(format)) sb.write(".$format");
  178. return sb.toString();
  179. }
  180. static Directory createTempDirSync({String package, String category}) {
  181. String path = getTempPath(package: package, category: category);
  182. return createDirSync(path);
  183. }
  184. static Directory createAppDocDirSync({String package, String category}) {
  185. String path = getAppDocPath(package: package, category: category);
  186. return createDirSync(path);
  187. }
  188. static Directory createStorageDirSync({String package, String category}) {
  189. String path = getStoragePath(package: package, category: category);
  190. return createDirSync(path);
  191. }
  192. static Future<Directory> createTempDir(
  193. {String package, String category}) async {
  194. await initTempDir();
  195. String path = getTempPath(package: package, category: category);
  196. return createDir(path);
  197. }
  198. static Future<Directory> createAppDocDir(
  199. {String package, String category}) async {
  200. await initAppDocDir();
  201. String path = getAppDocPath(package: package, category: category);
  202. return createDir(path);
  203. }
  204. static Future<Directory> createStorageDir(
  205. {String package, String category}) async {
  206. await initStorageDir();
  207. String path = getStoragePath(package: package, category: category);
  208. return createDir(path);
  209. }
  210. }