检查文件大小以确定更改 [英] Checking File sizes for changes

查看:146
本文介绍了检查文件大小以确定更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序可以查看传入作业的文件夹,然后处理它们。作业由文件夹中的多个作业文件组成。作业通常是通过互联网复制的,所以当一个文件夹添加到我的监视文件夹中我有我的应用程序获取的文件的属性在作业文件夹,等待20秒,并比较NSFileSize的当前属性,看看是否有是任何变化。当一切都匹配,并且没有检测到更改时,它可以传递作业文件夹以进行处理。这是我有的代码:

I have an app that watches a folder for incoming jobs and then processes them. A job consists of a Folder with several job files inside the folder. Jobs are usually copied over the internet so when a folder is added to my Watched Folder I'm having my app get the attributes for the files inside the job folder, wait 20 seconds, and compare the current attributes for NSFileSize to see if there have been any changes. When everything matches, and no changes are detected it can pass the job folder along to be processed. This is the code I have:

 while (fileSizes == NO && fileCount == NO) {
                            NSLog(@"going for a loop");
                            NSArray *jobFiles = [fm subpathsAtPath:jobPath];
                            NSMutableArray *jobFileAttrs = [[NSMutableArray alloc] init];
                            int i = 0;
                            while (i < [jobFiles count]) {
                                NSString *filePath = [jobPath stringByAppendingPathComponent:[jobFiles objectAtIndex:i]];
                                [jobFileAttrs addObject:[fm attributesOfItemAtPath:filePath error:nil]];
                                ++i;                      
                            }
                            sleep(20);
                            NSArray *jobFiles2 = [fm subpathsAtPath:jobPath];
                            NSMutableArray *jobFileAttrs2 = [[NSMutableArray alloc] init];
                            i = 0;
                            while (i < [jobFiles2 count]) {
                                NSString *filePath = [jobPath stringByAppendingPathComponent:[jobFiles2 objectAtIndex:i]];
                                [jobFileAttrs2 addObject:[fm attributesOfItemAtPath:filePath error:nil]];
                                ++i;                      
                            }

                            if ([jobFiles count] == [jobFiles2 count]) {
                                i = 0;
                                fileSizes = YES;
                                while (i < [jobFiles count]) {
                                    NSLog(@"Does %ul = %ul", [[jobFileAttrs objectAtIndex:i] objectForKey:NSFileSize], [[jobFileAttrs2 objectAtIndex:i] objectForKey:NSFileSize]);
                                    if ([[jobFileAttrs objectAtIndex:i] objectForKey:NSFileSize] != [[jobFileAttrs2 objectAtIndex:i] objectForKey:NSFileSize]){
                                        fileSizes = NO;
                                    }
                                    ++i;
                                }
                                if (fileSizes)
                                    fileCount = YES;
                            }

此代码在Lion中正常运行, Leopard我得到不一致的NSFileSize属性值。每次循环运行,我得到一个完全不同的值,甚至比以前的循环。这显然是一个文件夹的文件,不再被复制,并应该给文件大小匹配的值。

This code works as intended in Lion, but when I run the App on Snow Leopard I get inconsistent values for the NSFileSize attribute. Every time the loop runs I get a completely different set of value than even the previous loop. This is obviously for a folder full of files that is no longer being copied and should give matching values for the file sizes.

为什么这不工作在雪豹,我需要做什么来解决这个问题?我的问题的一部分是我只是设置在狮子机上的开发,所以我必须进行构建,然后将其转移到雪豹机器与一个调试器来测试。

Why doesn't this work in Snow Leopard, and what do I need to do to fix this? Part of my problem is I'm only set up for development on a Lion Machine, so I have to make build, and then transfer it to a snow leopard machine with out a debugger to test. It's making it hard for me to trouble shoot.

推荐答案

这里有一些问题,但一件事,你是比较使用布尔运算符(!= )的两个对象的值。这是比较两个对象的指针位置,而不是它们的值。

There are a few problems with this but for one thing, you are comparing the value of two objects using a boolean operator (!=). This is comparing the pointer locations of the two objects, not their value.

要比较两个对象,必须使用 isEqual:方法:

To compare two objects, you must use the isEqual: method:

if (![[[jobFileAttrs objectAtIndex:i] objectForKey:NSFileSize] isEqual:[[jobFileAttrs2 objectAtIndex:i] objectForKey:NSFileSize]])
{
    fileSizes = NO;
}

其次,这是根本不好的设计。你的代码所做的是调用轮询,并且在代码中存在 sleep()是一个坏的征兆。你不应该在Cocoa代码中使用 sleep ,特别是如果你的代码在主线程上执行,因为它会阻塞主运行循环。

Secondly, this is fundamentally bad design. What your code is doing is called polling, and the presence of sleep() in the code is a bad sign. You should never use sleep in Cocoa code, especially if your code is executing on the main thread as it will block the main run loop.

如果您绝对必须使用轮询,您应该使用 NSTimer 对象。

If you absolutely must use polling, you should use an NSTimer object.

但是,在这种特殊情况下,您不需要使用轮询来确定文件夹内容何时发生更改,您可以使用 FSEvents API 。 API是基于C的,有点暗,所以您可能想使用Stu Connolly的 SCEvents Objective-C包装器

However, in this particular case you don't need to use polling to determine when there has been a change to the folder contents, you can use the FSEvents API instead. The API is C-based and a bit obtuse so you might want to use Stu Connolly's SCEvents Objective-C wrapper.

你应该做的是维护当前文件及其文件大小(可能为 NSArray 实例变量包含具有文件名和文件属性的键的字典),然后当您收到磁盘上的更改通知时,获取磁盘上的更改的当前状态文件,并将其与存储的数组中的信息进行比较。

What you should be doing is maintaining an array of the current files and their file sizes (probably as an NSArray instance variable containing dictionaries with keys for file name and file attributes) and then when you are notified of a change on disk, get the current status of the files and compare that with the information in your stored array. You would then replace your stored array with the updated file information.

其他文件监视选项是 kqueues 。这些不同于 FSEvents ,因为它们特定于特定文件,而 FSEvents 监视目录,而不是单个文件。在你的情况下, kqueues 实际上可能更合适。 Uli Kusterer写了一个伟大的 kqueue的Objective-C包装。如果你使用这个,你只需要开始监视一个特定的文件,你会收到通知通知通过代理变化。这将是一个更简单的选项,如果你只需要一次检查一个文件。

The other file monitoring option is kqueues. These differ from FSEvents in that they are specific to a particular file, whereas FSEvents monitors directories, not individual files. In your case, kqueues may actually be more appropriate. Uli Kusterer has written a great Objective-C wrapper for kqueues. If you use this, you just need to start monitoring a particular file and you'll be notified whenever it changes via a delegate. This would be a simpler option if you only need to check one file at a time.

我希望这有意义。

这篇关于检查文件大小以确定更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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