JhtDocFileOperations.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //
  2. // JhtDocFileOperations.m
  3. // JhtDocViewerDemo
  4. //
  5. // GitHub主页: https://github.com/jinht
  6. // CSDN博客: http://blog.csdn.net/anticipate91
  7. //
  8. // Created by Jht on 2017/1/6.
  9. // Copyright © 2017年 JhtDocViewer. All rights reserved.
  10. //
  11. #import "JhtDocFileOperations.h"
  12. /** 系统默认 存放 从其他app分享过来文件的 文件夹名(后半段) */
  13. static NSString *const KJht_folderName_Default_OtherAppFiles = @"/Documents/Inbox";
  14. /** 存放 从其他app分享过来文件的 文件夹名(后半段) */
  15. static NSString *const KJht_folderName_OtherAppFiles = @"/Documents/JhtFolderNameWithOtherAppFiles";
  16. /** 默认 本地文件 加载到到内存中 文件夹名(后半段) */
  17. static NSString *const KJht_folderName_Default_LoadToMemoryFiles = @"Documents/JhtDoc";
  18. /** 系统默认 存放 下载文件的 文件夹名(后半段) */
  19. static NSString *const KJht_folderName_DownloadFiles = @"/Download/Files";
  20. @implementation JhtDocFileOperations
  21. /** 存放 app下载文件 沙盒路径 */
  22. @synthesize downloadFilesPath = _downloadFilesPath;
  23. /** 存放 从其他app分享过来文件 沙盒路径 */
  24. @synthesize otherAppFilesPath = _otherAppFilesPath;
  25. #pragma mark - Public Method
  26. + (instancetype)sharedInstance {
  27. static JhtDocFileOperations *JhtDocUtil = nil;
  28. static dispatch_once_t onceToken;
  29. dispatch_once(&onceToken, ^{
  30. if (JhtDocUtil == nil) {
  31. JhtDocUtil = [[self alloc] init];
  32. }
  33. });
  34. return JhtDocUtil;
  35. }
  36. #pragma mark 保存
  37. - (void)copyLocalWithFileName:(NSString *)fileName basePath:(NSString *)basePath localPath:(NSString *)localPath {
  38. // 兼容处理
  39. if (fileName.length == 0) {
  40. return;
  41. }
  42. if (localPath.length == 0) {
  43. localPath = KJht_folderName_Default_LoadToMemoryFiles;
  44. }
  45. if (basePath.length == 0) {
  46. basePath = NSHomeDirectory();
  47. }
  48. // 储存方式
  49. NSString *path = [basePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@", localPath, fileName]];
  50. NSFileManager *fileManager = [NSFileManager defaultManager];
  51. NSError *error;
  52. if (![fileManager fileExistsAtPath:path]) {
  53. // 创建目录
  54. [fileManager createDirectoryAtPath:[path componentsSeparatedByString:[NSString stringWithFormat:@"/%@", fileName]][0] withIntermediateDirectories:YES attributes:nil error:&error];
  55. NSString *filename = [fileName componentsSeparatedByString:@"."][0];
  56. NSString *type = [fileName componentsSeparatedByString:@"."][1];
  57. NSString *bundle = [[NSBundle mainBundle] pathForResource:filename ofType:type];
  58. // 用NSData保存到内存
  59. NSData *fileData = [[NSData alloc] initWithContentsOfFile:bundle];
  60. [fileData writeToFile:path atomically:YES];
  61. }
  62. }
  63. #pragma mark 生成路径
  64. - (NSString *)stitchLocalFilePath {
  65. // 生成 下载文件 沙盒路径
  66. NSString *filePath = [self stitchDownloadFilePath];
  67. NSString *fileTypePath = [filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", self.fileName]];
  68. return fileTypePath;
  69. }
  70. - (NSString *)stitchDownloadFilePath {
  71. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  72. NSString *downLoadPath = [paths objectAtIndex:0];
  73. NSString *downLoadFilesPath = [NSString stringWithFormat:@"%@%@", downLoadPath, KJht_folderName_DownloadFiles];
  74. return downLoadFilesPath;
  75. }
  76. - (NSString *)findLocalPathFromAppLicationOpenUrl:(NSURL *)url {
  77. // NSString *str = [NSString stringWithFormat:@"\n发送请求的应用程序的 Bundle ID: %@\n\n文件的NSURL: %@", options[UIApplicationOpenURLOptionsSourceApplicationKey], url];
  78. // url示例
  79. // @"file:///private/var/mobile/Containers/Data/Application/A2E0485F-1341-48A3-BD40-6D09CB8559F5/Documents/Inbox/2-6.pptx"
  80. /*
  81. // 从路径中获得完整的文件名(带后缀) 2.pptx
  82. NSString *exestr = ;
  83. NSLog(@"%@", exestr);
  84. // 获得文件名(不带后缀) file:/private/var/mobile/Containers/Data/Application/BEBCB59D-DAE2-4743-9421-62A64AFFCE0B/Documents/Inbox/2
  85. exestr = [[url description] stringByDeletingPathExtension];
  86. NSLog(@"%@", exestr);
  87. // 获得文件的后缀名(不带'.') pptx
  88. exestr = [[url description] pathExtension];
  89. NSLog(@"%@", exestr);
  90. */
  91. // url转码
  92. // NSLog(@"%@", url);
  93. NSString *urlStr = [[url description] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  94. // 将inbox里这个文档拷贝到KJht_folderName_OtherAppFiles目录下
  95. NSString *appfilePath = [self copyFromInboxWithFileName:[urlStr lastPathComponent]];
  96. // NSLog(@"%@", appfilePath);
  97. return appfilePath;
  98. }
  99. #pragma mark 清理
  100. - (void)removeFileWhenDownloadFileFailure {
  101. NSFileManager *fileManager = [NSFileManager defaultManager];
  102. NSString *fileName = [self stitchLocalFilePath];
  103. if ([fileManager fileExistsAtPath:fileName]) {
  104. [fileManager removeItemAtPath:fileName error:nil];
  105. }
  106. }
  107. - (void)cleanFileAfterDays:(CGFloat)day filePathArray:(NSArray *)filePathArray {
  108. // app下载文件 沙盒路径
  109. _downloadFilesPath = [self stitchDownloadFilePath];
  110. // 从别的app分享过来文件 沙盒路径
  111. _otherAppFilesPath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", KJht_folderName_OtherAppFiles]];
  112. NSArray *clearFilesPathArray = @[_downloadFilesPath, _otherAppFilesPath];
  113. if (filePathArray.count) {
  114. NSMutableArray *tempArray = [NSMutableArray arrayWithArray:clearFilesPathArray];
  115. [tempArray addObjectsFromArray:filePathArray];
  116. clearFilesPathArray = [tempArray copy];
  117. }
  118. // 并发异步 进行文件操作
  119. dispatch_queue_t queue = dispatch_queue_create("com.JhtDocViewerDemo", DISPATCH_QUEUE_SERIAL);
  120. dispatch_async(queue, ^{
  121. for (NSInteger i = 0; i < clearFilesPathArray.count; i ++) {
  122. NSString *filePath = clearFilesPathArray[i];
  123. NSFileManager *fileManager = [NSFileManager defaultManager];
  124. NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:filePath];
  125. NSString *path;
  126. while ((path = [directoryEnumerator nextObject]) != nil) {
  127. NSString *subFilePath = [filePath stringByAppendingPathComponent:path];
  128. // 遍历文件属性
  129. NSError *error = nil;
  130. NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:subFilePath error:&error];
  131. if (fileAttributes != nil) {
  132. NSDate *fileCreateDate = [fileAttributes objectForKey:NSFileCreationDate];
  133. if (fileCreateDate) {
  134. NSDate *nowDate = [NSDate date];
  135. NSTimeInterval timeInterval = [nowDate timeIntervalSinceDate:fileCreateDate];
  136. // 文件创建时间 与当前时间 间隔 > day ===> 删除
  137. // (2 * 60): 2min的延迟,避免误删除当次要打开的文件
  138. if (timeInterval > (day > 0 ? (day * 24 * 60 * 60) : (2 * 60))) {
  139. // 判断文件是否存在
  140. if ([fileManager fileExistsAtPath:subFilePath]) {
  141. [fileManager removeItemAtPath:subFilePath error:nil];
  142. }
  143. }
  144. }
  145. }
  146. }
  147. }
  148. });
  149. }
  150. #pragma mark - Private Method
  151. /** 将inbox里这个文档拷贝到KJht_folderName_OtherAppFiles文件夹下
  152. * fileName: Documents/Inbox文件夹下的文件名
  153. * return: 文件的新地址
  154. */
  155. - (NSString *)copyFromInboxWithFileName:(NSString *)fileName {
  156. // 其他app 分享过来的文件 默认存放的文件夹
  157. NSString *tempFileDir = [NSHomeDirectory() stringByAppendingString:KJht_folderName_Default_OtherAppFiles];
  158. // 文件的新地址
  159. NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@", KJht_folderName_OtherAppFiles, fileName]];
  160. // 创建KJht_folderName_OtherAppFiles文件夹
  161. NSFileManager *fileManager = [NSFileManager defaultManager];
  162. BOOL isDir = FALSE;
  163. BOOL isDirExist = [fileManager fileExistsAtPath:[NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", KJht_folderName_OtherAppFiles]] isDirectory:&isDir];
  164. if (!isDirExist) {
  165. NSError *error;
  166. [fileManager createDirectoryAtPath:[NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", KJht_folderName_OtherAppFiles]] withIntermediateDirectories:YES attributes:nil error:&error];
  167. }
  168. // 删除KJht_folderName_OtherAppFiles文件夹下所有文件
  169. // [self deleteWithLocalPath:[NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", KJht_folderName_OtherAppFiles]]];
  170. // 用NSData方式保存
  171. NSData *fileData = [[NSData alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", tempFileDir, fileName]];
  172. [fileData writeToFile:path atomically:YES];
  173. // 删除Inbox文件夹(文件所在的原始文件夹)下所有文件
  174. [self deleteWithLocalPath:tempFileDir];
  175. return path;
  176. }
  177. /** 删除文件下的所有所有文档 */
  178. - (void)deleteWithLocalPath:(NSString *)filePath {
  179. NSFileManager *fileManager = [NSFileManager defaultManager];
  180. NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:filePath];
  181. NSString *path;
  182. while ((path = [directoryEnumerator nextObject]) != nil) {
  183. NSString *subFilePath = [filePath stringByAppendingPathComponent:path];
  184. if ([fileManager fileExistsAtPath:subFilePath]) {
  185. // 如果存在
  186. [fileManager removeItemAtPath:subFilePath error:nil];
  187. }
  188. }
  189. }
  190. #pragma mark - Getter
  191. - (NSString *)downloadFilesPath {
  192. if (!_downloadFilesPath) {
  193. _downloadFilesPath = [self stitchDownloadFilePath];
  194. }
  195. return _downloadFilesPath;
  196. }
  197. - (NSString *)otherAppFilesPath {
  198. if (!_otherAppFilesPath) {
  199. _otherAppFilesPath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", KJht_folderName_OtherAppFiles]];
  200. }
  201. return _otherAppFilesPath;
  202. }
  203. @end