您好我在使用iNotify来检测目录中的更改。我使用的标志是IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE
我正在尝试区分重命名时的IN_MOVED_FROM
和文件移出文件夹时的IN_MOVED_FROM
。
cookie
字段是否不为0。我认为cookie
仅用于重命名程序。但是,即使我将文件移出目录,它仍然有一个cookie。IN_MODIFY
,因为我希望重命名但不会移动,但它不存在。有没有人对如何检测它是“刚搬出”还是“重命名来自旧文件名”有任何想法?
由于
答案 0 :(得分:2)
您需要检查IN_MOVED_FROM
事件和以下IN_MOVED_TO
事件。如果cookie相同,则文件已在同一文件夹中重命名。如果您没有收到具有相同Cookie的IN_MOVED_TO
事件,则该文件已移出监视文件夹。
答案 1 :(得分:1)
我应用@ hek2mgl的逻辑提及,并且它的工作如此之大,这要归功于他。这是js-ctypes代码:
while (true) {
let length = ostypes.API('read')(fd, buf, count);
length = parseInt(cutils.jscGetDeepest(length));
if (length == -1) {
throw new Error({
name: 'os-api-error',
message: 'Failed to read during poll',
uniEerrno: ctypes.errno
});
} else if (!length==0) {
// then its > 0 as its not -1
// something happend, read struct
let FSChanges = [];
var i = 0;
var numElementsRead = 0;
length = parseInt(cutils.jscGetDeepest(length));
var _cache_aRenamed_local = {}; // local means per buffer
do {
let iHoisted = i;
numElementsRead++;
var casted = ctypes.cast(buf.addressOfElement(iHoisted), ostypes.TYPE.inotify_event.ptr).contents;
var fileName = casted.addressOfField('name').contents.readString();
var mask = casted.addressOfField('mask').contents;
var len = casted.addressOfField('len').contents;
var cookie = cutils.jscGetDeepest(casted.addressOfField('cookie').contents)
var wd = casted.addressOfField('wd').contents;
var aEvent = convertFlagsToAEventStr(mask);
if (aEvent == 'renamed-to') {
if (cookie in _cache_aRenamed_local) { // assuming that renamed-from must happen before rename-to otherwise its a added
if (_cache_aRenamed_local[cookie].aExtra.aOSPath_parentDir_identifier == wd) { // aOSPath_parentDir_identifier is a wd if its different then the current wd then it was added/removed from that watched dir
var rezObj = {
aFileName: fileName,
aEvent: 'renamed',
aExtra: {
nixInotifyFlags: mask, // i should pass this, as if user did modify the flags, they might want to figure out what exactly changed
aOSPath_parentDir_identifier: wd,
aOld: {
aFileName: _cache_aRenamed_local[cookie].aFileName,
aExtra: {
nixInotifyFlags: _cache_aRenamed_local[cookie].aExtra.nixInotifyFlags
}
}
}
}
FSChanges.push(rezObj);
} else {
// the one in cache was removed from its parent folder, this one here was added to parent folder. so this is detect as file moved from one watched dir to another watched dir
if (_cache_aRenamed_local[cookie].aFileName != fileName) {
console.error('whaaaaa wd\'s are differnt and got renamed-to so names should be same');
_cache_aRenamed_local[cookie].aEvent = 'haaa names are different?? im just going to say REMOVED as a guess i have never encoutnered this situation yet and i dont think we ever should';
FSChanges.push(_cache_aRenamed_local[cookie]);
} else {
_cache_aRenamed_local[cookie].aEvent = 'removed';
FSChanges.push(_cache_aRenamed_local[cookie]);
}
}
delete _cache_aRenamed_local[cookie];
} else {
var rezObj = {
aFileName: fileName,
aEvent: 'added',
aExtra: {
aOSPath_parentDir_identifier: wd
}
}
FSChanges.push(rezObj);
}
} else if (aEvent == 'renamed-from') {
var rezObj = {
aFileName: fileName,
aEvent: aEvent,
aExtra: {
aOSPath_parentDir_identifier: wd
}
}
_cache_aRenamed_local[cookie] = rezObj;
} else {
var rezObj = {
aFileName: fileName,
aEvent: aEvent,
aExtra: {
aOSPath_parentDir_identifier: wd
}
}
FSChanges.push(rezObj);
}
if (len == 0) {
break;
};
i += nixStuff.sizeField0 + nixStuff.sizeField1 + nixStuff.sizeField2 + nixStuff.sizeField3 + parseInt(len);
} while (i < length);
for (var cookieLeft in _cache_aRenamed_local) {
// whatever is left in _cache_aRenamed_local is `removed` things
_cache_aRenamed_local[cookieLeft].aEvent = 'removed';
FSChanges.push(rezObj);
}
console.error('loop ended:', 'numElementsRead:', numElementsRead);
if (FSChanges.length > 0) {
return FSChanges;
} // else dont return and continue loop
}
}
我使用此函数将标志转换为类似renamed-from
或renamed-to
的字符串
function convertFlagsToAEventStr(flags) {
var default_flags = {
IN_CLOSE_WRITE: 'contents-modified',
IN_MOVED_TO: 'renamed-to', // can also be a added
IN_DELETE: 'removed',
IN_MOVED_FROM: 'renamed-from', // can also be a removed
IN_CREATE: 'added'
};
for (var f in default_flags) {
if (flags & ostypes.CONST[f]) {
return default_flags[f];
}
}
return 'UNKNOWN FLAG';
}