Преглед изворни кода

1.目前单个200M以内的上传OK 断点续传接口报错

huangxiaodong пре 10 месеци
родитељ
комит
622280e0c0

+ 12 - 0
创维盒子/双子星云手机.xcodeproj/project.pbxproj

@@ -1191,6 +1191,10 @@
 		6BED888B2B4E819000F76DDC /* downloadFileRecordTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BED88892B4E819000F76DDC /* downloadFileRecordTableView.m */; };
 		6BED888E2B4E901900F76DDC /* downloadFileRecordCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BED888C2B4E901900F76DDC /* downloadFileRecordCell.h */; };
 		6BED888F2B4E901900F76DDC /* downloadFileRecordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BED888D2B4E901900F76DDC /* downloadFileRecordCell.m */; };
+		6BEF9B852C64CDD300142B75 /* frpUploadModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BEF9B832C64CDD300142B75 /* frpUploadModel.h */; };
+		6BEF9B862C64CDD300142B75 /* frpUploadModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BEF9B842C64CDD300142B75 /* frpUploadModel.m */; };
+		6BEF9B872C64CDD300142B75 /* frpUploadModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BEF9B832C64CDD300142B75 /* frpUploadModel.h */; };
+		6BEF9B882C64CDD300142B75 /* frpUploadModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BEF9B842C64CDD300142B75 /* frpUploadModel.m */; };
 		6BF0F3D02AD391D8000AA133 /* connectDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BF0F3CE2AD391D8000AA133 /* connectDeviceManager.h */; };
 		6BF0F3D12AD391D8000AA133 /* connectDeviceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF0F3CF2AD391D8000AA133 /* connectDeviceManager.m */; };
 		6BF0F3D52AD3937B000AA133 /* DeviceThirdIdModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BF0F3D32AD3937B000AA133 /* DeviceThirdIdModel.h */; };
@@ -1969,6 +1973,8 @@
 		6BED88892B4E819000F76DDC /* downloadFileRecordTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = downloadFileRecordTableView.m; sourceTree = "<group>"; };
 		6BED888C2B4E901900F76DDC /* downloadFileRecordCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = downloadFileRecordCell.h; sourceTree = "<group>"; };
 		6BED888D2B4E901900F76DDC /* downloadFileRecordCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = downloadFileRecordCell.m; sourceTree = "<group>"; };
+		6BEF9B832C64CDD300142B75 /* frpUploadModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = frpUploadModel.h; sourceTree = "<group>"; };
+		6BEF9B842C64CDD300142B75 /* frpUploadModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = frpUploadModel.m; sourceTree = "<group>"; };
 		6BF0F3CE2AD391D8000AA133 /* connectDeviceManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = connectDeviceManager.h; sourceTree = "<group>"; };
 		6BF0F3CF2AD391D8000AA133 /* connectDeviceManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = connectDeviceManager.m; sourceTree = "<group>"; };
 		6BF0F3D32AD3937B000AA133 /* DeviceThirdIdModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceThirdIdModel.h; sourceTree = "<group>"; };
@@ -3272,6 +3278,8 @@
 				6B97739A2C637C4800213317 /* nasUploadManager.m */,
 				6B97739F2C637E3A00213317 /* nasUploadFileManager.h */,
 				6B9773A02C637E3A00213317 /* nasUploadFileManager.m */,
+				6BEF9B832C64CDD300142B75 /* frpUploadModel.h */,
+				6BEF9B842C64CDD300142B75 /* frpUploadModel.m */,
 			);
 			path = nasUploadManager;
 			sourceTree = "<group>";
@@ -3929,6 +3937,7 @@
 				6B8FF6C12B05B24D00800981 /* uploadFileRecordCell.h in Headers */,
 				6B45C5082B5FA2DD007E6911 /* diskListTableCell.h in Headers */,
 				183AE6D42A8CAFAE00B11CB0 /* UIView+View.h in Headers */,
+				6BEF9B852C64CDD300142B75 /* frpUploadModel.h in Headers */,
 				6B9354892BF2FE8700AA8D31 /* editTypeHeadView.h in Headers */,
 				6BC7414C2C240A670049BA8D /* webSocketManager+downloadFile.h in Headers */,
 				6B2C1E4A2C070ADE00FDCF82 /* ZFSpeedLoadingView.h in Headers */,
@@ -4198,6 +4207,7 @@
 				6BD506E22B9576A4006E7CB0 /* uploadFileRecordCell.h in Headers */,
 				6BD506E32B9576A4006E7CB0 /* diskListTableCell.h in Headers */,
 				6BD506E42B9576A4006E7CB0 /* UIView+View.h in Headers */,
+				6BEF9B872C64CDD300142B75 /* frpUploadModel.h in Headers */,
 				6B93548A2BF2FE8700AA8D31 /* editTypeHeadView.h in Headers */,
 				6BC7414E2C240A670049BA8D /* webSocketManager+downloadFile.h in Headers */,
 				6B2C1E4B2C070ADE00FDCF82 /* ZFSpeedLoadingView.h in Headers */,
@@ -4938,6 +4948,7 @@
 				6BD507A12B9576A4006E7CB0 /* uploadFileRecordCell.m in Sources */,
 				6BD507A22B9576A4006E7CB0 /* BaseNavigationController.m in Sources */,
 				6B34DC4F2BF1BA11002DD1EF /* previewImageOrVideoViewController.m in Sources */,
+				6BEF9B882C64CDD300142B75 /* frpUploadModel.m in Sources */,
 				6B2C1E6B2C070ADE00FDCF82 /* ZFLandscapeRotationManager_iOS16.m in Sources */,
 				6BD507A32B9576A4006E7CB0 /* HWFolderModel.m in Sources */,
 				6BD507A42B9576A4006E7CB0 /* fileTransferPathCheckViewController.m in Sources */,
@@ -5289,6 +5300,7 @@
 				6B8FF6C22B05B24D00800981 /* uploadFileRecordCell.m in Sources */,
 				A003F6A727D841C800715CBF /* BaseNavigationController.m in Sources */,
 				6B34DC4D2BF1BA11002DD1EF /* previewImageOrVideoViewController.m in Sources */,
+				6BEF9B862C64CDD300142B75 /* frpUploadModel.m in Sources */,
 				6B2C1E6A2C070ADE00FDCF82 /* ZFLandscapeRotationManager_iOS16.m in Sources */,
 				A00221E427EB256D00E45F78 /* HWFolderModel.m in Sources */,
 				6B5B606F2B3D7E3B009A2AE2 /* fileTransferPathCheckViewController.m in Sources */,

+ 3 - 0
创维盒子/双子星云手机/AppDelegate/PrefixHeader.pch

@@ -114,6 +114,9 @@ isBangsScreen; \
 //#define EachPieceSzie (512*1024) //每片上传文件大小切割
 #define EachPieceSzie (2*1024*1024) //每片上传文件大小切割
 #define cutVideoPieceSzie (3 * EachPieceSzie) //视频每次切片多少(切完上传再切一次)
+
+//#define MaxNasUploadPieceSzie (200*1024*1024) //frp上传 限制每片最大200M
+#define MaxNasUploadPieceSzie (10*1024*1024) //frp上传 限制每片最大200M
 #define keyToForgetPwd @"%==%"
 
 #define FileService            @"http://file.phone.androidscloud.com:8210/document/file/lowLevelMultipartUpload"

+ 1 - 1
创维盒子/双子星云手机/Class/Set/uploadFile/uploadFileRecordViewController.m

@@ -721,7 +721,7 @@
 - (void)RefreshUploadViewFun
 {
     KWeakSelf
-    [[uploadFileManager shareInstance] getDataInDatabaseFun:NO complete:^(NSMutableArray * _Nonnull Arr) {
+    [[nasUploadFileManager shareInstance] getDataInDatabaseFun:NO complete:^(NSMutableArray * _Nonnull Arr) {
         //[weakSelf setRecordBodyDataFunBy:Arr];
         
         if(!Arr ||Arr.count != 3){

+ 16 - 0
创维盒子/双子星云手机/NAS/nasUploadManager/frpUploadModel.h

@@ -0,0 +1,16 @@
+//
+//  frpUploadModel.h
+//  双子星云手机
+//
+//  Created by xd h on 2024/8/8.
+//
+
+#import "SuperModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface frpUploadModel : SuperModel
+@property(nonatomic,assign) NSInteger position; //原来位置 断点续传用
+@end
+
+NS_ASSUME_NONNULL_END

+ 12 - 0
创维盒子/双子星云手机/NAS/nasUploadManager/frpUploadModel.m

@@ -0,0 +1,12 @@
+//
+//  frpUploadModel.m
+//  双子星云手机
+//
+//  Created by xd h on 2024/8/8.
+//
+
+#import "frpUploadModel.h"
+
+@implementation frpUploadModel
+
+@end

+ 114 - 8
创维盒子/双子星云手机/NAS/nasUploadManager/nasUploadFileManager.m

@@ -323,7 +323,8 @@
     }
     
     if(!_curUploadFileDataModel.asset){
-        //[self getDataWrongToChangeFailFun];
+        self.curUploadFileDataModel.curUploadStateType = uploadStateFail;
+        [self nasUploadFileChangeingOneFileFunBy:self.curUploadFileDataModel];
         return;
     }
     
@@ -338,7 +339,8 @@
                         [weakSelf  afterGetImageDataFun];
                     }
                     else{
-                        //[weakSelf getDataWrongToChangeFailFun];
+                        weakSelf.curUploadFileDataModel.curUploadStateType = uploadStateFail;
+                        [weakSelf nasUploadFileChangeingOneFileFunBy:weakSelf.curUploadFileDataModel];
                     }
             }];
         }
@@ -349,8 +351,8 @@
         [[PHImageManager defaultManager] requestImageDataForAsset:_curUploadFileDataModel.asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                 // 直接得到最终的 NSData 数据
                 if (imageData) {
-                    self->_curUploadFileDataModel.imageData = imageData;
-                    //[weakSelf  afterGetImageDataInVideoFun];
+                    weakSelf.curUploadFileDataModel.imageData = imageData;
+                    [weakSelf  afterGetImageDataInVideoFun];
                 }
         }];
 
@@ -365,14 +367,16 @@
                 BOOL isSuc = [cachesFileManager copyVideoItemAtPath:[urlAsset.URL path] fileName:self->_curUploadFileDataModel.filename error:nil];
                 
                 if (isSuc) {
-                    //[weakSelf  afterGetVideoDataFun];
+                    [weakSelf  afterGetVideoDataFun];
                 }
                 else{
-                    //[weakSelf getDataWrongToChangeFailFun];
+                    self->_curUploadFileDataModel.curUploadStateType = uploadStateFail;
+                    [weakSelf nasUploadFileChangeingOneFileFunBy:self->_curUploadFileDataModel];
                 }
             }
             else{
-                //[weakSelf getDataWrongToChangeFailFun];
+                weakSelf.curUploadFileDataModel.curUploadStateType = uploadStateFail;
+                [weakSelf nasUploadFileChangeingOneFileFunBy:weakSelf.curUploadFileDataModel];
             }
         }];
     }
@@ -386,8 +390,110 @@
     [self beginGotoUploadDataFun];
 }
 
+#pragma mark 处理视频第一帧
+- (void)afterGetImageDataInVideoFun
+{
+    [cachesFileManager getFileNameWithContent:_curUploadFileDataModel.imageData fileName:_curUploadFileDataModel.videoFirstImageName type:uploadFileTypeImage];
+}
+
+#pragma mark 处理视频数据
+- (void)afterGetVideoDataFun
+{
+    [self beginGotoUploadDataFun];
+}
+
+
+#pragma mark 开始上传
 - (void)beginGotoUploadDataFun{
-    [[nasUploadManager shareInstance] beginUploadDataBy:_curUploadFileDataModel];
+    KWeakSelf
+    [[nasUploadManager shareInstance] beginUploadDataBy:_curUploadFileDataModel success:^(id  _Nonnull responseObject) {
+        weakSelf.curUploadFileDataModel.curUploadStateType = uploadStateDone;
+        [weakSelf nasUploadFileChangeingOneFileFunBy:weakSelf.curUploadFileDataModel];
+    } faild:^(NSError * _Nonnull error) {
+        weakSelf.curUploadFileDataModel.curUploadStateType = uploadStateFail;
+        [weakSelf nasUploadFileChangeingOneFileFunBy:weakSelf.curUploadFileDataModel];
+    }];
+}
+
+
+#pragma mark 更新数据状态
+- (void)nasUploadFileChangeingOneFileFunBy:(uploadFileDataModel*)dataModel
+{
+    
+    if(dataModel.curUploadStateType == uploadStateDone){
+        [_fileModelDataArr removeObject:dataModel];
+        [self handleDatabaseArrDeleteObjectInUploading:dataModel];
+        [self handleDatabaseArrAddObjectInDone:dataModel];
+    }
+    else if(dataModel.curUploadStateType == uploadStateFail){
+        [_fileModelDataArr removeObject:dataModel];
+        [self handleDatabaseArrDeleteObjectInUploading:dataModel];
+        [self handleDatabaseArrAddObjectInFail:dataModel];
+    }
+
+    [dataModel bg_saveOrUpdateAsync:^(BOOL isSuccess) {
+        //HLog(@"%@ 写入 %@", model.filename, isSuccess ? @"成功":@"失败");
+    }];
+        
+    
+    if(!_isSuspendType || dataModel.curUploadStateType != uploadStateSuspend){
+        [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileRefreshNotification object:dataModel];
+    }
+    
+}
+
+#pragma mark 删除上传中的任务
+- (void)handleDatabaseArrDeleteObjectInUploading:(uploadFileDataModel*)model
+{
+    NSLock *lock = [NSLock new];
+    [lock lock];
+    if(_databaseArr && _databaseArr.count == 3 ){
+        
+        NSMutableArray *ingArr = _databaseArr[0];
+        NSInteger count = ingArr.count;
+        [ingArr removeObject:model];
+        
+        NSInteger atferDelCount = ingArr.count;
+        
+        if(count == atferDelCount){
+            for (couldPhoneFileModel*preModel in ingArr) {
+                if(preModel.bg_id.integerValue == model.bg_id.integerValue){
+                    [ingArr removeObject:preModel];
+                    break;
+                }
+            }
+        }
+    }
+    [lock unlock];
+}
+
+#pragma mark 添加任务到上传完成
+- (void)handleDatabaseArrAddObjectInDone:(uploadFileDataModel*)model
+{
+    NSLock *lock = [NSLock new];
+    [lock lock];
+    if(_databaseArr && _databaseArr.count == 3 ){
+        NSMutableArray *doneArr = _databaseArr[1];
+        if(model){
+            [doneArr insertObject:model atIndex:0];
+        }
+    }
+    [lock unlock];
+}
+
+#pragma mark 添加任务到上传失败
+- (void)handleDatabaseArrAddObjectInFail:(uploadFileDataModel*)model
+{
+    NSLock *lock = [NSLock new];
+    [lock lock];
+    if(_databaseArr && _databaseArr.count == 3 ){
+        NSMutableArray *failArr = _databaseArr[2];
+        if(model){
+            [failArr insertObject:model atIndex:0];
+        }
+
+    }
+    [lock unlock];
 }
 
 @end

+ 1 - 1
创维盒子/双子星云手机/NAS/nasUploadManager/nasUploadManager.h

@@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
 @interface nasUploadManager : NSObject
 +(instancetype)shareInstance;
 
-- (void)beginUploadDataBy:(uploadFileDataModel*)dataModel;
+- (void)beginUploadDataBy:(uploadFileDataModel*)dataModel success:(netWork_Success)success faild:(netWork_Faild)faildStr;
 @end
 
 NS_ASSUME_NONNULL_END

+ 151 - 7
创维盒子/双子星云手机/NAS/nasUploadManager/nasUploadManager.m

@@ -8,6 +8,7 @@
 #import "nasUploadManager.h"
 #import "AFNetworkReachabilityManager.h"
 #import "AFHTTPSessionManager.h"
+#import "frpUploadModel.h"
 
 @interface nasUploadManager ()
 @property(nonatomic,strong)AFHTTPSessionManager *uploadManager;
@@ -54,8 +55,12 @@
         
         NSString *mimeType =@"application/octet-stream";
         if ([[params allKeys] containsObject:@"imageType"]) {
-            mimeType = @"jpg";
+            mimeType = @"image/jpeg";
         }
+        else if ([[params allKeys] containsObject:@"videoType"]) {
+            mimeType = @"video/mp4";
+        }
+        
         [formData appendPartWithFileData:data name:@"file" fileName:params[@"filename"] mimeType:mimeType];
         
     } progress:^(NSProgress * _Nonnull uploadProgress) {
@@ -70,7 +75,7 @@
     }];
 }
 
-- (void)beginUploadDataBy:(uploadFileDataModel*)dataModel
+- (void)beginUploadDataBy:(uploadFileDataModel*)dataModel success:(netWork_Success)success faild:(netWork_Faild)faildStr
 {
     NSMutableDictionary *paraDict = [NSMutableDictionary new];
     NSString* taskUid = [iTools getTaskUidStr];
@@ -93,18 +98,157 @@
         return;
     }
     
-    NSData *curData = dataModel.curUploadFileType == uploadFileTypeImage ? dataModel.imageData : dataModel.videoData;
-    
+    KWeakSelf
     if(dataModel.curUploadFileType == uploadFileTypeImage){
         [paraDict setObject:@1 forKey:@"imageType"];
+        NSData *curData = dataModel.imageData;
+        
+        [self nasUploadFileToFileServiceWithParams:paraDict data:curData success:^(id  _Nonnull responseObject) {
+            HLog(@"%@上传完成",dataModel.filename)
+            success(responseObject);
+        } faild:^(NSError * _Nonnull error) {
+            HLog(@"%@上传失败",dataModel.filename)
+            faildStr(error);
+        }];
+    }
+    else{
+        [paraDict setObject:@1 forKey:@"videoType"];
+        
+        //断点续传处理 先传1字节数据看服务器是否有数据
+        NSData *videoData = [self cutVideoFileFunAtIndex:0 withMaxLenght:1 withModel:dataModel];
+        [paraDict setObject:@0 forKey:@"isLast"];
+        
+       // NSData *videoData = [self cutVideoFileFunAtIndex:0 withMaxLenght:MaxNasUploadPieceSzie withModel:dataModel];
+        
+        
+        [self nasUploadFileToFileServiceWithParams:paraDict data:videoData success:^(id  _Nonnull responseObject) {
+            HLog(@"%@上传完成",dataModel.filename)
+            
+            frpUploadModel *model = [[frpUploadModel alloc] initWithDictionary:responseObject error:nil];
+            if(model && model.msg){
+                NSInteger curPosition = model.position > 0 ? model.position : 1;
+                [weakSelf beginUploadVideoDataFunBy:dataModel with:curPosition withPara:paraDict success:^(id  _Nonnull responseObject) {
+                    success(responseObject);
+                } faild:^(NSError * _Nonnull error) {
+                    faildStr(error);
+                }];
+            }
+            else{
+                NSError *err = [NSError new];
+                faildStr(err);
+            }
+        
+        } faild:^(NSError * _Nonnull error) {
+            HLog(@"%@上传失败",dataModel.filename)
+            faildStr(error);
+        }];
+    }
+    
+}
+
+- (void)beginUploadVideoDataFunBy:(uploadFileDataModel*)dataModel with:(NSInteger)position withPara:(NSMutableDictionary*)paraDict success:(netWork_Success)success faild:(netWork_Faild)faildStr
+{
+
+    BOOL isLastPicece = NO;
+    if((dataModel.totalBytes - position) <= MaxNasUploadPieceSzie){
+        [paraDict setObject:@1 forKey:@"isLast"];
+        isLastPicece = YES;
     }
     
+    [paraDict setObject:[NSNumber numberWithLong:position] forKey:@"position"];
+    
+    //视频数据切片
+    NSData *videoData = [self cutVideoFileFunAtIndex:position withMaxLenght:MaxNasUploadPieceSzie withModel:dataModel];
     
-    [self nasUploadFileToFileServiceWithParams:paraDict data:curData success:^(id  _Nonnull responseObject) {
-        HLog(@"上传完成")
+    KWeakSelf
+    [self nasUploadFileToFileServiceWithParams:paraDict data:videoData success:^(id  _Nonnull responseObject) {
+        HLog(@"%@上传完成",dataModel.filename)
+        
+        frpUploadModel *model = [[frpUploadModel alloc] initWithDictionary:responseObject error:nil];
+        if(model && model.msg){
+            if (isLastPicece) {
+                success(responseObject);
+            }
+            else{
+                [weakSelf beginUploadVideoDataFunBy:dataModel with:(position +MaxNasUploadPieceSzie) withPara:paraDict success:^(id  _Nonnull responseObject) {
+                   
+                } faild:^(NSError * _Nonnull error) {
+                    NSError *err = [NSError new];
+                    faildStr(err);
+                }];
+            }
+        }
+        else{
+            NSError *err = [NSError new];
+            faildStr(err);
+        }
+        
     } faild:^(NSError * _Nonnull error) {
-        HLog(@"上传失败")
+        HLog(@"%@上传失败",dataModel.filename)
+        faildStr(error);
     }];
 }
 
+#pragma mark 分段读视频文件
+-(NSData*)cutVideoFileFunAtIndex:(NSUInteger)dataIndex withMaxLenght:(NSInteger)maxLengt withModel:(uploadFileDataModel*)dataModel{
+    NSString *filePath = [cachesFileManager getFilePathWithName:dataModel.filename type:uploadFileTypeVideo]; // 文件路径
+    
+    NSFileManager *manager0 = [NSFileManager defaultManager];
+    if(![manager0 fileExistsAtPath:filePath]) {
+     
+        return [NSData new];
+    }
+    
+    NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath]; // 创建文件句柄
+      
+    // 设置分段读取的大小,这里以每次读取1KB为例
+    const NSUInteger chunkSize = maxLengt;//cutVideoPieceSzie;//5 * 1024 *1024;
+    NSMutableData *data = [NSMutableData data];
+    
+    if (fileHandle) {
+       
+        long long endOfFile = [fileHandle seekToEndOfFile];
+        
+        if(dataModel.totalBytes == 0
+           || dataModel.totalBytes < endOfFile){//异常处理
+            dataModel.totalBytes = endOfFile;
+        }
+        
+        //异常处理
+        if(endOfFile == dataIndex){
+            dataModel.totalBytes = endOfFile;
+            dataModel.didUploadBytes = endOfFile;
+            dataModel.curUploadStateType = uploadStateDone;
+            [fileHandle closeFile];
+            return  data;
+        }
+        
+        if (endOfFile >=  chunkSize) {
+            
+            // 读取文件的分段数据到某个位置
+            [fileHandle seekToFileOffset:dataIndex];
+            
+            // 读取文件的分段数据
+            NSData* chunk = [fileHandle readDataOfLength:chunkSize];
+            if (chunk) {
+                [data appendData:chunk];
+            }
+        }
+        else{
+            // 读取文件的分段数据到某个位置
+            [fileHandle seekToFileOffset:dataIndex];
+            
+            [data appendData:[fileHandle readDataToEndOfFile]];
+        }
+        
+        // 在这里可以对文件内容进行处理
+        // ...
+        
+        // 关闭文件句柄
+        [fileHandle closeFile];
+    }
+    
+    return data;
+}
+
 @end