CWFileManager.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. //
  2. // CWUploadTask.m
  3. // uploadFileDemo
  4. //
  5. // Created by hyjet on 2018/3/9.
  6. // Copyright © 2018年 uploadFileDemo. All rights reserved.
  7. #import "CWFileManager.h"
  8. @interface CWFileManager ()
  9. @property (strong, nonatomic) NSFileManager *manager;
  10. @end
  11. @implementation CWFileManager
  12. #pragma mark - 沙盒目录相关
  13. + (NSString *)homeDir {
  14. return NSHomeDirectory();
  15. }
  16. + (NSString *)documentsDir {
  17. return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
  18. }
  19. + (NSString *)libraryDir {
  20. return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];;
  21. }
  22. + (NSString *)preferencesDir {
  23. NSString *libraryDir = [self libraryDir];
  24. return [libraryDir stringByAppendingPathComponent:@"Preferences"];
  25. }
  26. + (NSString *)cachesDir {
  27. return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
  28. }
  29. + (NSString *)tmpDir {
  30. return NSTemporaryDirectory();
  31. }
  32. #pragma mark - 遍历文件夹
  33. + (NSArray *)listFilesInDirectoryAtPath:(NSString *)path deep:(BOOL)deep {
  34. NSArray *listArr;
  35. NSError *error;
  36. NSFileManager *manager = [NSFileManager defaultManager];
  37. if (deep) {
  38. // 深遍历
  39. NSArray *deepArr = [manager subpathsOfDirectoryAtPath:path error:&error];
  40. if (!error) {
  41. listArr = deepArr;
  42. }else {
  43. listArr = nil;
  44. }
  45. }else {
  46. // 浅遍历
  47. NSArray *shallowArr = [manager contentsOfDirectoryAtPath:path error:&error];
  48. if (!error) {
  49. listArr = shallowArr;
  50. }else {
  51. listArr = nil;
  52. }
  53. }
  54. return listArr;
  55. }
  56. + (NSArray *)listFilesInHomeDirectoryByDeep:(BOOL)deep {
  57. return [self listFilesInDirectoryAtPath:[self homeDir] deep:deep];
  58. }
  59. + (NSArray *)listFilesInLibraryDirectoryByDeep:(BOOL)deep {
  60. return [self listFilesInDirectoryAtPath:[self libraryDir] deep:deep];
  61. }
  62. + (NSArray *)listFilesInDocumentDirectoryByDeep:(BOOL)deep {
  63. return [self listFilesInDirectoryAtPath:[self documentsDir] deep:deep];
  64. }
  65. + (NSArray *)listFilesInTmpDirectoryByDeep:(BOOL)deep {
  66. return [self listFilesInDirectoryAtPath:[self tmpDir] deep:deep];
  67. }
  68. + (NSArray *)listFilesInCachesDirectoryByDeep:(BOOL)deep {
  69. return [self listFilesInDirectoryAtPath:[self cachesDir] deep:deep];
  70. }
  71. + (NSArray *)listFilesInCoustomDirectoryByDeep:(NSString*)path deepBool:(BOOL)deep{
  72. if (![CWFileManager isExistsAtPath:path]) {
  73. return @[];
  74. }
  75. return [self listFilesInDirectoryAtPath:path deep:deep];
  76. }
  77. #pragma mark - 获取文件属性
  78. + (id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key {
  79. return [[self attributesOfItemAtPath:path] objectForKey:key];
  80. }
  81. + (id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key error:(NSError *__autoreleasing *)error {
  82. return [[self attributesOfItemAtPath:path error:error] objectForKey:key];
  83. }
  84. + (NSDictionary *)attributesOfItemAtPath:(NSString *)path {
  85. return [self attributesOfItemAtPath:path error:nil];
  86. }
  87. + (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  88. return [[NSFileManager defaultManager] attributesOfItemAtPath:path error:error];
  89. }
  90. #pragma mark - 创建文件(夹)
  91. + (BOOL)createDirectoryAtPath:(NSString *)path {
  92. return [self createDirectoryAtPath:path error:nil];
  93. }
  94. + (BOOL)createDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  95. NSFileManager *manager = [NSFileManager defaultManager];
  96. BOOL isSuccess = [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:error];
  97. return isSuccess;
  98. }
  99. + (BOOL)createFileAtPath:(NSString *)path {
  100. return [self createFileAtPath:path content:nil overwrite:YES error:nil];
  101. }
  102. + (BOOL)createFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  103. return [self createFileAtPath:path content:nil overwrite:YES error:error];
  104. }
  105. + (BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite {
  106. return [self createFileAtPath:path content:nil overwrite:overwrite error:nil];
  107. }
  108. + (BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
  109. return [self createFileAtPath:path content:nil overwrite:overwrite error:error];
  110. }
  111. + (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content {
  112. return [self createFileAtPath:path content:content overwrite:YES error:nil];
  113. }
  114. + (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError *__autoreleasing *)error {
  115. return [self createFileAtPath:path content:content overwrite:YES error:error];
  116. }
  117. + (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content overwrite:(BOOL)overwrite {
  118. return [self createFileAtPath:path content:content overwrite:overwrite error:nil];
  119. }
  120. + (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
  121. // 如果文件夹路径不存在,那么先创建文件夹
  122. NSString *directoryPath = [self directoryAtPath:path];
  123. if (![self isExistsAtPath:directoryPath]) {
  124. // 创建文件夹
  125. if (![self createDirectoryAtPath:directoryPath error:error]) {
  126. return NO;
  127. }
  128. }
  129. // 如果文件存在,并不想覆盖,那么直接返回YES。
  130. if (!overwrite) {
  131. if ([self isExistsAtPath:path]) {
  132. return YES;
  133. }
  134. }
  135. // 创建文件
  136. BOOL isSuccess = [[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
  137. if (content) {
  138. [self writeFileAtPath:path content:content error:error];
  139. }
  140. return isSuccess;
  141. }
  142. + (NSDate *)creationDateOfItemAtPath:(NSString *)path {
  143. return [self creationDateOfItemAtPath:path error:nil];
  144. }
  145. + (NSDate *)creationDateOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  146. return (NSDate *)[self attributeOfItemAtPath:path forKey:NSFileCreationDate error:error];
  147. }
  148. + (NSDate *)modificationDateOfItemAtPath:(NSString *)path {
  149. return [self modificationDateOfItemAtPath:path error:nil];
  150. }
  151. + (NSDate *)modificationDateOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  152. return (NSDate *)[self attributeOfItemAtPath:path forKey:NSFileModificationDate error:error];
  153. }
  154. #pragma mark - 删除文件(夹)
  155. + (BOOL)removeItemAtPath:(NSString *)path {
  156. return [self removeItemAtPath:path error:nil];
  157. }
  158. + (BOOL)removeItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  159. return [[NSFileManager defaultManager] removeItemAtPath:path error:error];
  160. }
  161. + (BOOL)clearCachesDirectory {
  162. NSArray *subFiles = [self listFilesInCachesDirectoryByDeep:NO];
  163. BOOL isSuccess = YES;
  164. for (NSString *file in subFiles) {
  165. NSString *absolutePath = [[self cachesDir] stringByAppendingPathComponent:file];
  166. isSuccess &= [self removeItemAtPath:absolutePath];
  167. }
  168. return isSuccess;
  169. }
  170. + (BOOL)clearTmpDirectory {
  171. NSArray *subFiles = [self listFilesInTmpDirectoryByDeep:NO];
  172. BOOL isSuccess = YES;
  173. for (NSString *file in subFiles) {
  174. NSString *absolutePath = [[self tmpDir] stringByAppendingPathComponent:file];
  175. isSuccess &= [self removeItemAtPath:absolutePath];
  176. }
  177. return isSuccess;
  178. }
  179. #pragma mark - 复制文件(夹)
  180. + (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath {
  181. return [self copyItemAtPath:path toPath:toPath overwrite:NO error:nil];
  182. }
  183. + (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError *__autoreleasing *)error {
  184. return [self copyItemAtPath:path toPath:toPath overwrite:NO error:error];
  185. }
  186. + (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite {
  187. return [self copyItemAtPath:path toPath:toPath overwrite:overwrite error:nil];
  188. }
  189. + (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
  190. // 先要保证源文件路径存在,不然抛出异常
  191. if (![self isExistsAtPath:path]) {
  192. [NSException raise:@"非法的源文件路径" format:@"源文件路径%@不存在,请检查源文件路径", path];
  193. return NO;
  194. }
  195. NSString *toDirPath = [self directoryAtPath:toPath];
  196. if (![self isExistsAtPath:toDirPath]) {
  197. // 创建复制路径
  198. if (![self createDirectoryAtPath:toDirPath error:error]) {
  199. return NO;
  200. }
  201. }
  202. // 如果覆盖,那么先删掉原文件
  203. if (overwrite) {
  204. if ([self isExistsAtPath:toPath]) {
  205. [self removeItemAtPath:toPath error:error];
  206. }
  207. }
  208. // 复制文件
  209. BOOL isSuccess = [[NSFileManager defaultManager] copyItemAtPath:path toPath:toPath error:error];
  210. return isSuccess;
  211. }
  212. #pragma mark - 移动文件(夹)
  213. + (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath {
  214. return [self moveItemAtPath:path toPath:toPath overwrite:NO error:nil];
  215. }
  216. + (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError *__autoreleasing *)error {
  217. return [self moveItemAtPath:path toPath:toPath overwrite:NO error:error];
  218. }
  219. + (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite {
  220. return [self moveItemAtPath:path toPath:toPath overwrite:overwrite error:nil];
  221. }
  222. + (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
  223. // 先要保证源文件路径存在,不然抛出异常
  224. if (![self isExistsAtPath:path]) {
  225. [NSException raise:@"非法的源文件路径" format:@"源文件路径%@不存在,请检查源文件路径", path];
  226. return NO;
  227. }
  228. NSString *toDirPath = [self directoryAtPath:toPath];
  229. if (![self isExistsAtPath:toDirPath]) {
  230. // 创建移动路径
  231. if (![self createDirectoryAtPath:toDirPath error:error]) {
  232. return NO;
  233. }
  234. }
  235. // 如果覆盖,那么先删掉原文件
  236. if ([self isExistsAtPath:toPath]) {
  237. if (overwrite) {
  238. [self removeItemAtPath:toPath error:error];
  239. }else {
  240. [self removeItemAtPath:path error:error];
  241. return YES;
  242. }
  243. }
  244. // 移动文件 用copy复制 不要用move剪切
  245. BOOL isSuccess = [[NSFileManager defaultManager] copyItemAtPath:path toPath:toPath error:error];
  246. return isSuccess;
  247. }
  248. #pragma mark - 根据URL获取文件名
  249. + (NSString *)fileNameAtPath:(NSString *)path suffix:(BOOL)suffix {
  250. NSString *fileName = [path lastPathComponent];
  251. if (!suffix) {
  252. fileName = [fileName stringByDeletingPathExtension];
  253. }
  254. return fileName;
  255. }
  256. + (NSString *)directoryAtPath:(NSString *)path {
  257. return [path stringByDeletingLastPathComponent];
  258. }
  259. + (NSString *)suffixAtPath:(NSString *)path {
  260. return [path pathExtension];
  261. }
  262. #pragma mark - 判断文件(夹)是否存在
  263. + (BOOL)isExistsAtPath:(NSString *)path {
  264. return [[NSFileManager defaultManager] fileExistsAtPath:path];
  265. }
  266. + (BOOL)isEmptyItemAtPath:(NSString *)path {
  267. return [self isEmptyItemAtPath:path error:nil];
  268. }
  269. + (BOOL)isEmptyItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  270. return ([self isFileAtPath:path error:error] &&
  271. [[self sizeOfItemAtPath:path error:error] intValue] == 0) ||
  272. ([self isDirectoryAtPath:path error:error] &&
  273. [[self listFilesInDirectoryAtPath:path deep:NO] count] == 0);
  274. }
  275. + (BOOL)isDirectoryAtPath:(NSString *)path {
  276. return [self isDirectoryAtPath:path error:nil];
  277. }
  278. + (BOOL)isDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  279. return ([self attributeOfItemAtPath:path forKey:NSFileType error:error] == NSFileTypeDirectory);
  280. }
  281. + (BOOL)isFileAtPath:(NSString *)path {
  282. return [self isFileAtPath:path error:nil];
  283. }
  284. + (BOOL)isFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  285. return ([self attributeOfItemAtPath:path forKey:NSFileType error:error] == NSFileTypeRegular);
  286. }
  287. + (BOOL)isExecutableItemAtPath:(NSString *)path {
  288. return [[NSFileManager defaultManager] isExecutableFileAtPath:path];
  289. }
  290. + (BOOL)isReadableItemAtPath:(NSString *)path {
  291. return [[NSFileManager defaultManager] isReadableFileAtPath:path];
  292. }
  293. + (BOOL)isWritableItemAtPath:(NSString *)path {
  294. return [[NSFileManager defaultManager] isWritableFileAtPath:path];
  295. }
  296. #pragma mark - 获取文件(夹)大小
  297. + (NSNumber *)sizeOfItemAtPath:(NSString *)path {
  298. return [self sizeOfItemAtPath:path error:nil];
  299. }
  300. + (NSNumber *)sizeOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  301. return (NSNumber *)[self attributeOfItemAtPath:path forKey:NSFileSize error:error];
  302. }
  303. + (NSNumber *)sizeOfFileAtPath:(NSString *)path {
  304. return [self sizeOfFileAtPath:path error:nil];
  305. }
  306. + (NSNumber *)sizeOfFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  307. if ([self isFileAtPath:path error:error]) {
  308. return [self sizeOfItemAtPath:path error:error];
  309. }
  310. return nil;
  311. }
  312. + (NSNumber *)sizeOfDirectoryAtPath:(NSString *)path {
  313. return [self sizeOfDirectoryAtPath:path error:nil];
  314. }
  315. + (NSNumber *)sizeOfDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  316. if ([self isDirectoryAtPath:path error:error]) {
  317. NSArray *subPaths = [self listFilesInDirectoryAtPath:path deep:YES];
  318. NSEnumerator *contentsEnumurator = [subPaths objectEnumerator];
  319. NSString *file;
  320. unsigned long long int folderSize = 0;
  321. while (file = [contentsEnumurator nextObject]) {
  322. NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[path stringByAppendingPathComponent:file] error:nil];
  323. folderSize += [[fileAttributes objectForKey:NSFileSize] intValue];
  324. }
  325. return [NSNumber numberWithUnsignedLongLong:folderSize];
  326. }
  327. return nil;
  328. }
  329. + (NSString *)sizeFormattedOfItemAtPath:(NSString *)path {
  330. return [self sizeFormattedOfItemAtPath:path error:nil];
  331. }
  332. + (NSString *)sizeFormattedOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  333. NSNumber *size = [self sizeOfItemAtPath:path error:error];
  334. if (size) {
  335. return [self sizeFormatted:size];
  336. }
  337. return nil;
  338. }
  339. + (NSString *)sizeFormattedOfFileAtPath:(NSString *)path {
  340. return [self sizeFormattedOfFileAtPath:path error:nil];
  341. }
  342. + (NSString *)sizeFormattedOfFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  343. NSNumber *size = [self sizeOfFileAtPath:path error:error];
  344. if (size) {
  345. return [self sizeFormatted:size];
  346. }
  347. return nil;
  348. }
  349. + (NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path {
  350. return [self sizeFormattedOfDirectoryAtPath:path error:nil];
  351. }
  352. + (NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
  353. NSNumber *size = [self sizeOfDirectoryAtPath:path error:error];
  354. if (size) {
  355. return [self sizeFormatted:size];
  356. }
  357. return nil;
  358. }
  359. #pragma mark - 写入文件内容
  360. + (BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content {
  361. return [self writeFileAtPath:path content:content error:nil];
  362. }
  363. + (BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError *__autoreleasing *)error {
  364. if (!content) {
  365. [NSException raise:@"非法的文件内容" format:@"文件内容不能为nil"];
  366. return NO;
  367. }
  368. if ([self isExistsAtPath:path]) {
  369. if ([content isKindOfClass:[NSMutableArray class]]) {
  370. [(NSMutableArray *)content writeToFile:path atomically:YES];
  371. }else if ([content isKindOfClass:[NSArray class]]) {
  372. [(NSArray *)content writeToFile:path atomically:YES];
  373. }else if ([content isKindOfClass:[NSMutableData class]]) {
  374. [(NSMutableData *)content writeToFile:path atomically:YES];
  375. }else if ([content isKindOfClass:[NSData class]]) {
  376. [(NSData *)content writeToFile:path atomically:YES];
  377. }else if ([content isKindOfClass:[NSMutableDictionary class]]) {
  378. [(NSMutableDictionary *)content writeToFile:path atomically:YES];
  379. }else if ([content isKindOfClass:[NSDictionary class]]) {
  380. [(NSDictionary *)content writeToFile:path atomically:YES];
  381. }else if ([content isKindOfClass:[NSJSONSerialization class]]) {
  382. [(NSDictionary *)content writeToFile:path atomically:YES];
  383. }else if ([content isKindOfClass:[NSMutableString class]]) {
  384. [[((NSString *)content) dataUsingEncoding:NSUTF8StringEncoding] writeToFile:path atomically:YES];
  385. }else if ([content isKindOfClass:[NSString class]]) {
  386. [[((NSString *)content) dataUsingEncoding:NSUTF8StringEncoding] writeToFile:path atomically:YES];
  387. }else if ([content isKindOfClass:[UIImage class]]) {
  388. [UIImagePNGRepresentation((UIImage *)content) writeToFile:path atomically:YES];
  389. }else if ([content conformsToProtocol:@protocol(NSCoding)]) {
  390. [NSKeyedArchiver archiveRootObject:content toFile:path];
  391. }else {
  392. [NSException raise:@"非法的文件内容" format:@"文件类型%@异常,无法被处理。", NSStringFromClass([content class])];
  393. return NO;
  394. }
  395. }else {
  396. return NO;
  397. }
  398. return YES;
  399. }
  400. #pragma mark - private methods
  401. + (BOOL)isNotError:(NSError **)error {
  402. return ((error == nil) || ((*error) == nil));
  403. }
  404. +(NSString *)sizeFormatted:(NSNumber *)size {
  405. return [NSByteCountFormatter stringFromByteCount:[size unsignedLongLongValue] countStyle:NSByteCountFormatterCountStyleFile];
  406. }
  407. @end