iOS文件操作基础

NSFileHandle

方法描述
+(NSFileHandle *)fileHandleForReadingAtPath:path打开文件以便读取
+(NSFileHandle *)fileHandleForWritingAtPath:path打开文件以便写入
+(NSFileHandle *)fileHandleForUpdatingAtPath:path打开文件以便读写
-(NSData *)availableData返回文件有效字符长度(bytes),有个问题是,如果在超大文件中用该方法,内存会暴涨直到卡死,该方法会将文件读入内存,然后计算长度,此时文件句柄指向文件结尾。
-(NSData *)readDataToEndOfFile读取文件末尾处之前的数据
-(NSData *)readDataOfLength:(NSUInteger)bytes读取指定长度的字节.这里也有个问题:当你存储汉字的时候,如果读取的字节数正好把一个汉字分多次读取,NSData中是有数据的.但是不能用NSString打印出来,此时打印出来为null.
-(void)writeData:data将数据data写入文件
-(unsigned long long)offsetInFile获取当前文件中的操作位置
-(void)seekToFileOffset:offset将当前文件的操作位置设定为offset
-(unsigned long long)seekToEndOfFile返回整个文件大小,并将读写指针移到文件尾部.该方法和上面的一个方法都是在磁盘上操作的,并没有将文件读到内存
-(void)truncateFileAtOffset:offset将文件的长度设定为offset
-(void)closeFile关闭文件

读取文件

//读取对应路径下的文件大小

+ (unsigned long long)getSizeWithFilePath:(nonnull NSString *)filePath error:(NSError **)error
{
    NSFileManager *fm = [NSFileManager defaultManager];
    NSDictionary *attributes = [fm attributesOfItemAtPath:filePath error:error];
    return attributes.fileSize;
}

    /**
     NSFileHandle *fileHande = [NSFileHandle fileHandleForReadingAtPath:filePath];
     return [fileHande seekToEndOfFile];
     */

//读取对应路径下的文件

+ (NSData *)fileData:(NSString *)filePath {
    /**
     NSError *readError;
     NSFileHandle *fileHande = [NSFileHandle fileHandleForReadingFromURL:[NSURL URLWithString:filePath] error:&readError];
     if (!readError) {
     NSData *readData = [fileHande readDataToEndOfFile];
     [fileHande closeFile];
     return readData;
     }
     //也闪退
     NSFileHandle *fileHande = [NSFileHandle fileHandleForReadingAtPath:filePath];
     return [fileHande readDataToEndOfFile];
     */
    
    NSFileHandle *fileHande = [NSFileHandle fileHandleForReadingAtPath:filePath];
    return [fileHande availableData];
}

注意:以上读取文件的方式只适用于小文件读取,小于5M或者再大点,如果是大文件的读取,app内存会暴涨,绝壁会闪退。具体原因见 iOS读取文件闪退

操作文件

文件分片

uint64_t offset = uplodFile.totalBytes / chuckCount;//每个分片大小 = 总大小 / 分片数量
for (int i = 1; i <= chuckCount; i++) {
	//打开文件
    NSFileHandle* readHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
    //seek文件
    [readHandle seekToFileOffset:offset * (i -1)];
    //读取每个分片中的文件
    NSData* data = [readHandle readDataOfLength:offset];
}

获取文件类型后缀

[NSString stringWithFormat:@".%@",[filePath pathExtension]];

获取文件的MINIType

- (NSString *)getMIMETypeWithCAPIAtFilePath:(NSString *)path
{
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        return nil;
    }
    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
    CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
    CFRelease(UTI);
    if (!MIMEType) {
        return @"application/octet-stream";//任意的二进制文件
    }
    return (__bridge NSString *)(MIMEType);
}

获取文件大小

+ (unsigned long long)getSizeWithFilePath:(nonnull NSString *)filePath error:(NSError **)error
{
    /**
     NSFileHandle *fileHande = [NSFileHandle fileHandleForReadingAtPath:filePath];
     return [fileHande seekToEndOfFile];
     */
    NSFileManager *fm = [NSFileManager defaultManager];
    NSDictionary *attributes = [fm attributesOfItemAtPath:filePath error:error];
    return attributes.fileSize;
}

//计算文件的大小,单位为 M,这种计算大文件绝壁闪退

- (CGFloat)fileSize:(NSURL *)url {
    return [[NSData dataWithContentsOfURL:url] length] / 1024.00 / 1024.00;
}

文件另存和删除

int32_t const VH_CHUNK_SIZE = 8 * 1024;

//另存为
- (NSString *)writefile:(NSString *)filePath
{
    //写入文件路径
    NSString *toPath = [NSString stringWithFormat:@"%@/%@",NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject,[filePath lastPathComponent]];
    //如果存在,先删除
    if ([[NSFileManager defaultManager] fileExistsAtPath:toPath]) {
        [[NSFileManager defaultManager] removeItemAtPath:toPath error:nil];
    }
    //创建文件路径
    if (![[NSFileManager defaultManager] createFileAtPath:toPath contents:nil attributes:nil]) {
        return nil;
    }
    //打开文件
    NSFileHandle *sourceHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
    NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:toPath];
    if(sourceHandle == nil || writeHandle == nil) {
        return nil;
    }
    //读取文件写入
    BOOL done = NO;
    while(!done) {
        @autoreleasepool{
            NSData *data = [sourceHandle readDataOfLength:VH_CHUNK_SIZE];
            if([data length] == 0) {
                done = YES;
            }
            [writeHandle seekToEndOfFile];
            [writeHandle writeData:data];
            data = nil;
        }
    }
    //关闭文件
    [sourceHandle closeFile];
    [writeHandle closeFile];
    return toPath;
}
//删除本地上传的文件
- (BOOL)deletefile:(NSString *)uploadPath {
    if ([[NSFileManager defaultManager] fileExistsAtPath:uploadPath]) {
        BOOL removed = [[NSFileManager defaultManager] removeItemAtPath:uploadPath error:nil];
        OSSLogDebug(@"removed file %@ %@",uploadPath,removed?@"sucess":@"failed");
        return removed;
    }
    return NO;
}

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morris_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值