DocInteraction 检测本地目录…
2014-01-23 17:32
302 查看
#import
@class
DirectoryWatcher;
@protocol
DirectoryWatcherDelegate <<span style="color:
#703daa">NSObject>
@required
- (void)directoryDidChange:(DirectoryWatcher *)folderWatcher;
@end
@interface DirectoryWatcher :
NSObject
{
id <</span>DirectoryWatcherDelegate>
delegate;
int dirFD;
int kq;
CFFileDescriptorRef dirKQRef;
}
@property (nonatomic,
assign) id <</span>DirectoryWatcherDelegate> delegate;
+ (DirectoryWatcher
*)watchFolderWithPath:(NSString
*)watchPath delegate:(id<<span style="color:
#4f8187">DirectoryWatcherDelegate>)watchDelegate;
- (void)invalidate;
@end
----------------------------------------------------------------------------------------------------------------
#import
"DirectoryWatcher.h"
#include
#include
#include
#include
#include
#import
@interface DirectoryWatcher
(DirectoryWatcherPrivate)
- (BOOL)startMonitoringDirectory:(NSString
*)dirPath;
- (void)kqueueFired;
@end
#pragma mark -
@implementation
DirectoryWatcher
@synthesize delegate;
- (id)init
{
self= [super init];
delegate = NULL;
dirFD = -1;
kq = -1;
dirKQRef = NULL;
return self;
}
- (void)dealloc
{
[self invalidate];
[super dealloc];
}
+ (DirectoryWatcher *)watchFolderWithPath:(NSString *)watchPath
delegate:(id)watchDelegate
{
DirectoryWatcher *retVal = NULL;
if ((watchDelegate !=
NULL) && (watchPath !=
NULL))
{
DirectoryWatcher *tempManager = [[[DirectoryWatcher alloc] init]
autorelease];
tempManager.delegate = watchDelegate;
if ([tempManager
startMonitoringDirectory: watchPath])
{
// Everything appears to be in order, so return the
DirectoryWatcher.
// Otherwise we'll fall through and return NULL.
retVal = tempManager;
}
}
return retVal;
}
- (void)invalidate
{
if (dirKQRef != NULL)
{
CFFileDescriptorInvalidate(dirKQRef);
CFRelease(dirKQRef);
dirKQRef = NULL;
// We don't need to close the kq, CFFileDescriptorInvalidate closed
it instead.
// Change the value so no one thinks it's still live.
kq = -1;
}
if(dirFD != -1)
{
close(dirFD);
dirFD = -1;
}
}
@end
#pragma mark -
@implementation
DirectoryWatcher (DirectoryWatcherPrivate)
- (void)kqueueFired
{
assert(kq >= 0);
struct kevent event;
struct timespec timeout = {0, 0};
int
eventCount;
eventCount = kevent(kq,
NULL, 0, &event, 1, &timeout);
assert((eventCount >=
0) && (eventCount <
2));
// call our delegate of the directory change
[delegate
directoryDidChange:self];
CFFileDescriptorEnableCallBacks(dirKQRef,
kCFFileDescriptorReadCallBack);
}
static void KQCallback(CFFileDescriptorRef kqRef,
CFOptionFlags callBackTypes, void *info)
{
DirectoryWatcher *obj;
obj = (DirectoryWatcher
*)info;
assert([obj
isKindOfClass:[DirectoryWatcher class]]);
assert(kqRef ==
obj->dirKQRef);
assert(callBackTypes ==
kCFFileDescriptorReadCallBack);
[obj kqueueFired];
}
- (BOOL)startMonitoringDirectory:(NSString
*)dirPath
{
// Double initializing is not going to work...
if ((dirKQRef == NULL) && (dirFD == -1) && (kq == -1))
{
// Open the directory we're going to watch
dirFD = open([dirPath fileSystemRepresentation], O_EVTONLY);
if (dirFD >= 0)
{
// Create a kqueue for our event messages...
kq = kqueue();
if (kq >= 0)
{
struct kevent eventToAdd;
eventToAdd.ident = dirFD;
eventToAdd.filter = EVFILT_VNODE;
eventToAdd.flags = EV_ADD | EV_CLEAR;
eventToAdd.fflags = NOTE_WRITE;
eventToAdd.data = 0;
eventToAdd.udata = NULL;
int errNum = kevent(kq,
&eventToAdd, 1,
NULL, 0, NULL);
if (errNum == 0)
{
CFFileDescriptorContext context = { 0, self, NULL, NULL, NULL };
CFRunLoopSourceRef
rls;
// Passing true in the third argument so CFFileDescriptorInvalidate
will close kq.
dirKQRef = CFFileDescriptorCreate(NULL, kq, true, KQCallback, &context);
if (dirKQRef != NULL)
{
rls = CFFileDescriptorCreateRunLoopSource(NULL, dirKQRef, 0);
if (rls != NULL)
{
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls,
kCFRunLoopDefaultMode);
CFRelease(rls);
CFFileDescriptorEnableCallBacks(dirKQRef,
kCFFileDescriptorReadCallBack);
// If everything worked, return early and bypass shutting things
down
return YES;
}
// Couldn't create a runloop source, invalidate and release the
CFFileDescriptorRef
CFFileDescriptorInvalidate(dirKQRef);
CFRelease(dirKQRef);
dirKQRef = NULL;
}
}
// kq is active, but something failed, close the handle...
close(kq);
kq = -1;
}
// file handle is open, but something failed, close the
handle...
close(dirFD);
dirFD = -1;
}
}
return NO;
}
@end
@class
DirectoryWatcher;
@protocol
DirectoryWatcherDelegate <<span style="color:
#703daa">NSObject>
@required
- (void)directoryDidChange:(DirectoryWatcher *)folderWatcher;
@end
@interface DirectoryWatcher :
NSObject
{
id <</span>DirectoryWatcherDelegate>
delegate;
int dirFD;
int kq;
CFFileDescriptorRef dirKQRef;
}
@property (nonatomic,
assign) id <</span>DirectoryWatcherDelegate> delegate;
+ (DirectoryWatcher
*)watchFolderWithPath:(NSString
*)watchPath delegate:(id<<span style="color:
#4f8187">DirectoryWatcherDelegate>)watchDelegate;
- (void)invalidate;
@end
----------------------------------------------------------------------------------------------------------------
#import
"DirectoryWatcher.h"
#include
#include
#include
#include
#include
#import
@interface DirectoryWatcher
(DirectoryWatcherPrivate)
- (BOOL)startMonitoringDirectory:(NSString
*)dirPath;
- (void)kqueueFired;
@end
#pragma mark -
@implementation
DirectoryWatcher
@synthesize delegate;
- (id)init
{
self= [super init];
delegate = NULL;
dirFD = -1;
kq = -1;
dirKQRef = NULL;
return self;
}
- (void)dealloc
{
[self invalidate];
[super dealloc];
}
+ (DirectoryWatcher *)watchFolderWithPath:(NSString *)watchPath
delegate:(id)watchDelegate
{
DirectoryWatcher *retVal = NULL;
if ((watchDelegate !=
NULL) && (watchPath !=
NULL))
{
DirectoryWatcher *tempManager = [[[DirectoryWatcher alloc] init]
autorelease];
tempManager.delegate = watchDelegate;
if ([tempManager
startMonitoringDirectory: watchPath])
{
// Everything appears to be in order, so return the
DirectoryWatcher.
// Otherwise we'll fall through and return NULL.
retVal = tempManager;
}
}
return retVal;
}
- (void)invalidate
{
if (dirKQRef != NULL)
{
CFFileDescriptorInvalidate(dirKQRef);
CFRelease(dirKQRef);
dirKQRef = NULL;
// We don't need to close the kq, CFFileDescriptorInvalidate closed
it instead.
// Change the value so no one thinks it's still live.
kq = -1;
}
if(dirFD != -1)
{
close(dirFD);
dirFD = -1;
}
}
@end
#pragma mark -
@implementation
DirectoryWatcher (DirectoryWatcherPrivate)
- (void)kqueueFired
{
assert(kq >= 0);
struct kevent event;
struct timespec timeout = {0, 0};
int
eventCount;
eventCount = kevent(kq,
NULL, 0, &event, 1, &timeout);
assert((eventCount >=
0) && (eventCount <
2));
// call our delegate of the directory change
[delegate
directoryDidChange:self];
CFFileDescriptorEnableCallBacks(dirKQRef,
kCFFileDescriptorReadCallBack);
}
static void KQCallback(CFFileDescriptorRef kqRef,
CFOptionFlags callBackTypes, void *info)
{
DirectoryWatcher *obj;
obj = (DirectoryWatcher
*)info;
assert([obj
isKindOfClass:[DirectoryWatcher class]]);
assert(kqRef ==
obj->dirKQRef);
assert(callBackTypes ==
kCFFileDescriptorReadCallBack);
[obj kqueueFired];
}
- (BOOL)startMonitoringDirectory:(NSString
*)dirPath
{
// Double initializing is not going to work...
if ((dirKQRef == NULL) && (dirFD == -1) && (kq == -1))
{
// Open the directory we're going to watch
dirFD = open([dirPath fileSystemRepresentation], O_EVTONLY);
if (dirFD >= 0)
{
// Create a kqueue for our event messages...
kq = kqueue();
if (kq >= 0)
{
struct kevent eventToAdd;
eventToAdd.ident = dirFD;
eventToAdd.filter = EVFILT_VNODE;
eventToAdd.flags = EV_ADD | EV_CLEAR;
eventToAdd.fflags = NOTE_WRITE;
eventToAdd.data = 0;
eventToAdd.udata = NULL;
int errNum = kevent(kq,
&eventToAdd, 1,
NULL, 0, NULL);
if (errNum == 0)
{
CFFileDescriptorContext context = { 0, self, NULL, NULL, NULL };
CFRunLoopSourceRef
rls;
// Passing true in the third argument so CFFileDescriptorInvalidate
will close kq.
dirKQRef = CFFileDescriptorCreate(NULL, kq, true, KQCallback, &context);
if (dirKQRef != NULL)
{
rls = CFFileDescriptorCreateRunLoopSource(NULL, dirKQRef, 0);
if (rls != NULL)
{
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls,
kCFRunLoopDefaultMode);
CFRelease(rls);
CFFileDescriptorEnableCallBacks(dirKQRef,
kCFFileDescriptorReadCallBack);
// If everything worked, return early and bypass shutting things
down
return YES;
}
// Couldn't create a runloop source, invalidate and release the
CFFileDescriptorRef
CFFileDescriptorInvalidate(dirKQRef);
CFRelease(dirKQRef);
dirKQRef = NULL;
}
}
// kq is active, but something failed, close the handle...
close(kq);
kq = -1;
}
// file handle is open, but something failed, close the
handle...
close(dirFD);
dirFD = -1;
}
}
return NO;
}
@end
相关文章推荐
- vxWorks&nbsp;BSP主要文件目录的组成及…
- Discuz!&nbsp;X2.0后台检测邮件发…
- Opencv2.3&nbsp;图像特征检测总结
- 启动JvisualVM提示"无法检测到本地java应用程序"的解决方案
- 检测网络营销效果分析 (SMM tools)
- 运行&nbsp;CMD竟然转不了目录
- vb2008&nbsp;文件目录相关(2)
- javaScript js 在客户端 本地生成…
- Git&nbsp;本地管理
- ASM&nbsp;磁盘、目录的管理
- 利用Perl&nbsp;Net::Ping检测网段IP是否…
- (转)Android SDK目录结构和工具介…
- [DB2]在本地数据库目录或系统数据库目录中已经存在数据库别名""的解决办法
- yiisoft/yii2-apidoc 扩展应用实践
- vb2008&nbsp;文件目录相关
- 学习了目录操作函数 编写了一个源…
- 快速激活iPhone&nbsp;本地中文jailbreakme上线
- SQL&nbsp;2008发布本地订阅,在设置时出…
- MyEclipse8.5 更改javadoc 各项属…
- 文件目录创建失败 解决方法