iTunes文件共享应用程序:实时监控传入的数据 [英] iTunes File Sharing app: realtime monitoring for incoming datas

查看:178
本文介绍了iTunes文件共享应用程序:实时监控传入的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发iOS项目,支持iTunes文件共享功能。目标是实时跟踪传入/更改的数据。



我正在使用(有点修改) DirectoryWatcher 类代码
,并尝试此源代码



数据是NSBundle(* .bundle),一些包在100-500 MB范围内,取决于它的内容,一些视频/音频的东西。这些软件包里面有基于xml的描述符文件。



问题是上面这些代码中的任何一个触发了通知复制,但不是当复制/更改/删除过程完成完成时。



接下来尝试:

检查文件属性:

  NSDictionary * fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:零]; 
BOOL fileBusy = [[fileAttrs objectForKey:NSFileBusy] boolValue];

寻找 fileSize 变化: (NSURL * contURL in tempBundleURLs){
NSInteger lastSize = 0;

  dispatch_async(_checkQueue,^ {

NSDictionary * fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
NSInteger fileSize = [[fileAttrs objectForKey:NSFileSize] intValue];

{
lastSize = fileSize;
[NSThread sleepForTimeInterval:1];
$ b fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
fileSize = [[fileAttrs objectForKey:NSFileSize] intValue];

NSLog(@doing job);
} while(lastSize!= fileSize);

NSLog(@next job);
}
);

任何其他解决方案?

解决方案上面的工作伟大的bin文件,但不是.bundle(因为.bundle文件实际上是目录)。为了使它与.bundle一起工作,你应该在.bundle里面迭代每个文件。 你可以使用GCD的dispatch sources机制 - 使用它你可以观察特定的系统事件(在你的情况下,这是vnode类型的事件,因为你正在使用文件系统)。
为特定的目录设置观察者,我使用这样的代码:

$ $ $ $ $ $ $ - $(dispatch_source_t)fileSystemDispatchSourceAtPath :( NSString * )path
{
int fileDescr = open([path fileSystemRepresentation],O_EVTONLY); //观察特定路径的文件系统事件 - 你可以在这里传递Documents目录路径
//观察者队列是我的私人dispatch_queue_t对象
dispatch_source_t源= dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fileDescr,DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_LINK | DISPATCH_VNODE_EXTEND,observerQueue); //创建dispatch_source对象,观察虚拟节点事件
dispatch_source_set_registration_handler(来源^ {
NSLog(@registered for observation);
//每次发生选定类型的文件系统事件(DISPATCH_VNODE_ *)时,都会调用事件处理函数
dispatch_source_set_event_handler(source,^ {

dispatch_source_vnode_fla gs_t flags = dispatch_source_get_data(source); //获得标志
NSLog(@%lu,flags);

if(flags& DISPATCH_VNODE_WRITE)// flag每当数据附加到文件
{
NSLog(@DISPATCH_VNODE_WRITE)时被设置为DISPATCH_VNODE_WRITE;
NSDictionary * dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
float size = [[dict valueForKey:NSFileSize] floatValue];
NSLog(@%f,size);

if(flags& DISPATCH_VNODE_ATTRIB)//当文件被完全写入时,这个标志被传递。
{
NSLog(@DISPATCH_VNODE_ATTRIB);
dispatch_source_cancel(source);

if(flags& DISPATCH_VNODE_LINK)
{
NSLog(@DISPATCH_VNODE_LINK);

if(flags& DISPATCH_VNODE_EXTEND)
{
NSLog(@DISPATCH_VNODE_EXTEND);
}
NSLog(@file =%@,path);
NSLog(@\\\
\\\
);
});

dispatch_source_set_cancel_handler(source,^ {
close(fileDescr);
});
});

//我们必须恢复dispatch_objects
dispatch_resume(source);

返回来源;
}


I'm working on iOS project that supports iTunes file sharing feature. The goal is realtime tracking incoming/changed data's.

I'm using (kinda modified) DirectoryWatcher class from Apple's sample code and also tried this source code.

The data is NSBundle (*.bundle) and some bundles are in 100-500 MB ranges, depends on its content, some video/audio stuff. The bundles has xml based descriptor file in it.

The problem is any of these codes above fires notification or whatever else when the data just started copying and but not when the copy/change/remove process finished completely.

Tried next:

checking file attributes:

NSDictionary *fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
BOOL fileBusy = [[fileAttrs objectForKey:NSFileBusy] boolValue];

looking for the fileSize changes:

dispatch_async(_checkQueue, ^{
    for (NSURL *contURL in tempBundleURLs) {
        NSInteger lastSize = 0;
        NSDictionary *fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
        NSInteger fileSize = [[fileAttrs objectForKey:NSFileSize] intValue];

        do {
            lastSize = fileSize;
            [NSThread sleepForTimeInterval:1];

            fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:[contURL path] error:nil];
            fileSize = [[fileAttrs objectForKey:NSFileSize] intValue];

            NSLog(@"doing job");
        } while (lastSize != fileSize);

        NSLog(@"next job");
    }
);

any other solutions?

The solution above works great for bin files, but not for .bundle (as .bundle files are directory actually). In order to make it work with .bundle, you should iterate each file inside .bundle

解决方案

You can use GCD's dispatch sources mechanism - using it you can observe particular system events (in your case, this is vnode type events, since you're working with file system). To setup observer for particular directory, i used code like this:

- (dispatch_source_t) fileSystemDispatchSourceAtPath:(NSString*) path
{
    int fileDescr = open([path fileSystemRepresentation], O_EVTONLY);// observe file system events for particular path - you can pass here Documents directory path
    //observer queue is my private dispatch_queue_t object
    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fileDescr, DISPATCH_VNODE_ATTRIB| DISPATCH_VNODE_WRITE|DISPATCH_VNODE_LINK|DISPATCH_VNODE_EXTEND, observerQueue);// create dispatch_source object to observe vnode events
    dispatch_source_set_registration_handler(source, ^{
        NSLog(@"registered for observation");
        //event handler is called each time file system event of selected type (DISPATCH_VNODE_*) has occurred
        dispatch_source_set_event_handler(source, ^{

            dispatch_source_vnode_flags_t flags = dispatch_source_get_data(source);//obtain flags
            NSLog(@"%lu",flags);

            if(flags & DISPATCH_VNODE_WRITE)//flag is set to DISPATCH_VNODE_WRITE every time data is appended to file
            {
                NSLog(@"DISPATCH_VNODE_WRITE");
                NSDictionary* dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
                float size = [[dict valueForKey:NSFileSize] floatValue];
                NSLog(@"%f",size);
            }
            if(flags & DISPATCH_VNODE_ATTRIB)//this flag is passed when file is completely written.
            {
                NSLog(@"DISPATCH_VNODE_ATTRIB");
                dispatch_source_cancel(source);
            }
            if(flags & DISPATCH_VNODE_LINK)
            {
                NSLog(@"DISPATCH_VNODE_LINK");
            }
            if(flags & DISPATCH_VNODE_EXTEND)
            {
                NSLog(@"DISPATCH_VNODE_EXTEND");
            }
            NSLog(@"file = %@",path);
            NSLog(@"\n\n");
        });

        dispatch_source_set_cancel_handler(source, ^{
            close(fileDescr);
        });
    });

    //we have to resume dispatch_objects
    dispatch_resume(source);

    return source;
}

这篇关于iTunes文件共享应用程序:实时监控传入的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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