Objective c NSFileHandleDataAvailableNotification仅发送一次
在我的应用程序中,我设置了一个Objective c NSFileHandleDataAvailableNotification仅发送一次,objective-c,cocoa,Objective C,Cocoa,在我的应用程序中,我设置了一个NSFileHandle,以便在文件更新时(尝试)读取文件。但是,第一次修改文件时,我只收到一个通知。waitForDataInBackgroundAndNotify是从NSApplication的子类调用的,因此存在一个活动的runloop。我认为唯一可能影响这一点的问题是,编写文件的过程使用NSDictionarywriteToFile和原子性:true。这是个问题吗? 我还缺什么吗 FWIW,我可以用runloop中的计时器替换通知,并以这种方式读取文件。有点
NSFileHandle
,以便在文件更新时(尝试)读取文件。但是,第一次修改文件时,我只收到一个通知。waitForDataInBackgroundAndNotify
是从NSApplication
的子类调用的,因此存在一个活动的runloop。我认为唯一可能影响这一点的问题是,编写文件的过程使用NSDictionary
writeToFile
和原子性:true
。这是个问题吗?我还缺什么吗 FWIW,我可以用runloop中的计时器替换通知,并以这种方式读取文件。有点违背了回调的目的 设置文件句柄
- (void)setupRead:(id)sender
{
self.fileHandle = [NSFileHandle fileHandleForReadingAtPath:@"/path/to/some/file.xml"];
if( self.fileHandle == nil )
{
[self.taskLabel setStringValue:@"Error:"];
[self.taskText setStringValue:@"Unable to connect to status file"];
return;
}
// register for notifications
[self.fileHandle waitForDataInBackgroundAndNotify];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readData:) name:NSFileHandleDataAvailableNotification object:nil];
}
读取回调
- (void)readData:(NSNotification*)note
{
NSData* msg = [self.fileHandle availableData];
if( [msg length] )
{
NSError* error = nil;
NSDictionary* statusDictionary = [NSPropertyListSerialization propertyListWithData:msg options:NSPropertyListImmutable format:nil error:&error];
[self displayStatus:statusDictionary];
}
[self.fileHandle waitForDataInBackgroundAndNotify];
}
你试过非原子化写作吗?我过去也做过类似的事情,这就是问题所在。即使写入不是原子的(原子=写入tmp,然后替换文件,非原子=截断并写入),
availableData
读取到文件末尾,所以不需要文件句柄保持打开状态。如果外部进程将进行非原子写入,fh的读取位置(也称为seek)无论如何都不是零,因此您不能在不倒带的情况下“重新读取”。不幸的是,我无法控制写入程序,因此更改为非原子写入最多也会有问题。我确实尝试添加seekToFileOffset,但每次读取都收到相同的数据。也就是说,我收到了NSFileHandleDataAvailableNotification,但数据始终与初始数据相同。有趣。我似乎在从“旧”文件获取数据时收到了来自“新”文件的通知。