如何确定调用moveItemAtURL:toURL:或replaceItemAtURL:WithItemAtURL时需要多少时间: [英] how to determine how much time needed when calling moveItemAtURL:toURL: or replaceItemAtURL:WithItemAtURL:

查看:736
本文介绍了如何确定调用moveItemAtURL:toURL:或replaceItemAtURL:WithItemAtURL时需要多少时间:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将文件从一个位置移动到另一个位置或替换文件时,我总是使用 moveItemAtURL:toURL: replaceItemAtURL:WithItemAtURL方法: 来自 NSFileManager

When moving file from one place to another, or when replacing file, I always use the methods moveItemAtURL:toURL: or replaceItemAtURL:WithItemAtURL: from NSFileManager.

调用这些方法时,我想确定多少时间因此,我可以使用 NSProgressIndicator 告诉用户需要多长时间。就像您使用OSX移动文件时一样,它会告诉您还剩多少时间。

When calling these methods, I want to determine how much time needed, so that I can use the NSProgressIndicator to tell users how long it's going to take. Just like when you are moving file using OSX, it tells u how much time remaining.

我看过苹果文档,但找不到任何相关信息。
想知道是否可以实施,请提出建议。

I have looked at the apple doc but couldn't find any information regarding this. Wondering if this can be implemented, please advise.

推荐答案

您无法预先知道它会持续多久采取。您可以做的是在复制文件时计算完成百分比。但要做到这一点,您需要使用较低级别的API。您可以使用NSFileManagers attributesOfItemAtPath:error 来获取文件大小和用于复制的NSStreams(执行此操作的方法有很多)。完成百分比为 bytesWritten / totalBytesInFile

You can't know in advance haw long it going to take. What you can do is compute the "percent complete" while you are copying the file. But to do that you need to use lower level APIs. You can use NSFileManagers attributesOfItemAtPath:error to get the file size and NSStreams for doing the copying (there are so many way to do this). Percent complete is bytesWritten / totalBytesInFile.

---编辑:将示例代码添加为NSURL上的类别,并带有回调块传递写入的字节总数,完成的百分比和估计的剩余时间(以秒为单位)。

--- added sample code as a category on NSURL with a callback block passing the total number of bytes written, percen complete and estimated time left in seconds.

#import <mach/mach_time.h>

@interface NSURL(CopyWithProgress)<NSObject>
- (void) copyFileURLToURL:(NSURL*)destURL withProgressBlock:(void(^)(double, double, double))block;
@end

@implementation NSURL(CopyWithProgress)

- (void) copyFileURLToURL:(NSURL*)destURL
        withProgressBlock:(void(^)(double, double, double))block
{
    ///
    // NOTE: error handling has been left out in favor of simplicity
    //       real production code should obviously handle errors.
    NSUInteger fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil].fileSize;

    NSInputStream  *fileInput  = [NSInputStream inputStreamWithURL:self];
    NSOutputStream *copyOutput = [NSOutputStream outputStreamWithURL:destURL append:NO];

    static size_t bufferSize = 4096;
    uint8_t *buffer = malloc(bufferSize);
    size_t   bytesToWrite;
    size_t   bytesWritten;
    size_t   copySize = 0;
    size_t   counter  = 0;

    [fileInput open];
    [copyOutput open];

    uint64_t time0 = mach_absolute_time();

    while (fileInput.hasBytesAvailable) {
        do {
            bytesToWrite = [fileInput read:buffer maxLength:bufferSize];
            bytesWritten = [copyOutput write:buffer maxLength:bytesToWrite];
            bytesToWrite -= bytesWritten;
            copySize     += bytesWritten;
            if (bytesToWrite > 0)
                memmove(buffer, buffer + bytesWritten, bytesToWrite);
        }
        while (bytesToWrite > 0);

        if (block != nil && ++counter % 10 == 0) {
            double percent  = (double)copySize / fileSize;
            uint64_t time1  = mach_absolute_time();
            double elapsed  = (double)(time1 - time0)/NSEC_PER_SEC;
            double estTimeLeft = ((1 - percent) / percent) * elapsed;
            block(copySize, percent, estTimeLeft);
        }
    }

    if (block != nil)
        block(copySize, 1, 0);
}

@end


int main (int argc, const char * argv[])
{
    @autoreleasepool {

        NSURL *fileURL = [NSURL URLWithString:@"file:///Users/eric/bin/data/english-words.txt"];
        NSURL *destURL = [NSURL URLWithString:@"file:///Users/eric/Desktop/english-words.txt"];

        [fileURL copyFileURLToURL:destURL withProgressBlock:^(double bytes, double pct, double estSecs) {
            NSLog(@"Bytes=%f, Pct=%f, time left:%f s",bytes,pct,estSecs);
        }];
    }
    return 0;
}

样本输出:

Bytes=40960.000000, Pct=0.183890, time left:0.000753 s
Bytes=81920.000000, Pct=0.367780, time left:0.004336 s
Bytes=122880.000000, Pct=0.551670, time left:0.002672 s
Bytes=163840.000000, Pct=0.735560, time left:0.001396 s
Bytes=204800.000000, Pct=0.919449, time left:0.000391 s
Bytes=222742.000000, Pct=1.000000, time left:0.000000 s

这篇关于如何确定调用moveItemAtURL:toURL:或replaceItemAtURL:WithItemAtURL时需要多少时间:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆