【问题标题】:How to show the progress of copying a large file in iOS?如何在iOS中显示复制大文件的进度?
【发布时间】:2012-05-02 13:30:27
【问题描述】:

我正在编写一个 iOS 应用程序。在我的应用程序中,我想将一些文件从一个文件夹复制到另一个文件夹。 但由于有些文件太大,复制完成需要很长时间。所以我想添加一个进度条来显示副本的百分比。但是我发现文件管理器没有回调方法来获取百分比。有没有人有好的解决方法?

【问题讨论】:

    标签: objective-c ios copy progress-bar


    【解决方案1】:

    在高层:

    1. 在单独的线程 (T1) 中运行您的复制过程
    2. 运行另一个线程 (T2),它会定期(比如每 100 毫秒)读取目标文件 current_size
    3. 计算百分比:current_size / total_size
    4. 更新进度条 ui 元素

    【讨论】:

    • 你的意思是 current_size 是@interface NSDictionary (NSFileAttributes) - (unsigned long long)fileSize;?
    • NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:self.finalPath error:NULL]; unsigned long long fileSize = [属性文件大小];从这里拿走:stackoverflow.com/a/9479903/986169
    【解决方案2】:

    我用@giorashc 方法创建了一个简单的类。

    如果有人需要这样的东西,请随意使用它。

    .h

    #import <UIKit/UIKit.h>
    
    @protocol IDCopyUtilsDelegate;
    
    @interface IDCopyUtils : NSObject
    
    @property (nonatomic, weak) id<IDCopyUtilsDelegate> delegate;
    
    - (void)copyFileAtPath:(NSString *)sourcePath toPath:(NSString *)targetPath;
    
    @end
    
    // 3. Definition of the delegate's interface
    @protocol IDCopyUtilsDelegate <NSObject>
    
    - (void)setCopyProgress:(float)progress;
    - (void)didFinishedCopyWithError:(NSError *)error;
    
    @end
    

    .m

    #import "IDCopyUtils.h"
    
    @interface IDCopyUtils()
    
    @property (nonatomic, strong) NSTimer *timer;
    @property (nonatomic, strong) NSString *sourcePath;
    @property (nonatomic, strong) NSString *targetPath;
    
    @end
    
    @implementation IDCopyUtils
    
    - (void)copyFileAtPath:(NSString *)sourcePath toPath:(NSString *)targetPath
    {
        self.sourcePath = sourcePath;
        self.targetPath = targetPath;
    
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *error;
    
        if ([fileManager fileExistsAtPath:self.targetPath] == YES) {
            [fileManager removeItemAtPath:self.targetPath error:&error];
        }
    
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.100
                                         target:self
                                       selector:@selector(checkFileSize)
                                       userInfo:nil
                                        repeats:YES];
    
        [self performSelector:@selector(startCopy) withObject:nil afterDelay:0.5];
    
    }
    
    - (void)checkFileSize
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSDictionary *attributesSource = [[NSFileManager defaultManager] attributesOfItemAtPath:self.sourcePath error:NULL]; unsigned long long fileSize = [attributesSource fileSize];
    
            NSDictionary *attributesTarget = [[NSFileManager defaultManager] attributesOfItemAtPath:self.targetPath error:NULL]; unsigned long long fileSizeTarget = [attributesTarget fileSize];
    
            double progress = (float)fileSizeTarget / (float)fileSize;
    
            if (self.delegate && [self.delegate respondsToSelector:@selector(setCopyProgress:)])
            {
                [self.delegate setCopyProgress:progress];
            }
    
            NSLog(@"Size: %f", progress);
        });
    }
    
    - (void)startCopy
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSFileManager *fileManager = [NSFileManager defaultManager];
            NSError *error;
    
            if ([fileManager fileExistsAtPath:self.targetPath] == YES) {
                [fileManager removeItemAtPath:self.targetPath error:&error];
            }
    
            if ([fileManager fileExistsAtPath:self.targetPath] == NO) {
                [fileManager copyItemAtPath:self.sourcePath toPath:self.targetPath error:&error];
    
                [self.timer invalidate];
                self.timer = nil;
    
                if (self.delegate && [self.delegate respondsToSelector:@selector(didFinishedCopyWithError:)])
                {
                    [self.delegate didFinishedCopyWithError:error];
                }
            }
        });
    }
    
    @end
    

    你可以这样使用它(例如):

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    
    NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"iso"];
    NSString *targetPath = [documentsDirectory stringByAppendingPathComponent:@"test.iso"];
    
    IDCopyUtils *copyUtils = [[IDCopyUtils alloc] init];
    copyUtils.delegate = self;
    [copyUtils copyFileAtPath:sourcePath toPath:targetPath];
    

    我们将能够更新您的进度视图,并在文件使用委托方法完成复制时收到通知。

    【讨论】:

      猜你喜欢
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多