JavaScript, как программно заблокировать открытый файл?
Я использую следующую функцию для записи данных в формате JSON в файл в Cordova. Работает просто отлично. Проблема заключается в том, что мое приложение записывает данные в этот файл в нескольких местах, и иногда этот файл пересекается, как правило, когда пользователь очень быстро переключается между различными разделами приложения. Когда это происходит, это приводит к тому, что одни и те же данные json записываются дважды. Когда это происходит, это вызывает неправильный формат файла json - поэтому в следующий раз, когда я пойду, чтобы прочитать этот файл, он выдаст ошибку с ошибкой синтаксического анализа json.
Пример данных:
var jObj = {
"This" : "Test1",
"That" : "Test2"
}
И когда происходит двойная запись, файл выглядит так:
{
"This" : "Test1",
"That" : "Test2"
}{
"This" : "Test1",
"That" : "Test2"
}
А потому что нет ,
между }{
в скобках это вызывает ошибку синтаксического анализа JSON при следующем чтении файла. Как я могу предотвратить запись данных дважды? Мне нужен какой-то метод, который предотвращает повторную запись, когда первая запись имеет открытый файл.
Ниже приведена моя функция записи файла: (Мое специальное решение - добавить глобальную переменную блокировки файла wfOpen = 0
к оригинальной функции записи)
function writeToFile(fileName, data, dir) {
if (dir == 1) {
var filePath = cordova.file.applicationDirectory ;
} else {
var filePath = cordova.file.dataDirectory ;
}
data = JSON.stringify(data, null, '\t');
window.resolveLocalFileSystemURL(filePath, function (directoryEntry) {
directoryEntry.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwrite = function (e) {
wfOpen = 0 ; // unlock global fileLock, set to false
errMgmt("index/writeToFile",1152,fileName +" - successfully written") ;
};
fileWriter.onerror = function (e) {
wfOpen = 0 ; // unlock global fileLock, set to false
errMgmt("index/writeToFile",1153,fileName+ " - failed to write") ;
};
var blob = new Blob([data], { type: 'text/json' });
fileWriter.write(blob);
},function(e) {errorHandler(fileName,e,1154)}) ;
}, function(e) {errorHandler(fileName,e,1155)}) ;
},function(e) {errorHandler(fileName,e,1156)}) ;
}
Мое решение - пользовательская блокировка файла, пожалуйста, прокомментируйте, если это хорошо или нет. Вызывайте функцию записи, только если глобальная переменная равна false. Если в данный момент происходит запись, задайте для глобальной переменной значение true (файл заблокирован), а затем запустите отложенный цикл до тех пор, пока глобальная переменная не станет ложной, прежде чем пытаться выполнить запись снова.
var wfOpen = 0 ; //global fileLock far
function wUserData() {
if (wfOpen == 0) {
wfOpen = 1 ; // set global file lock to locked/true
console.log("writing to userdata.json") ;
writeToFile("userdata.json",userData) ;
} else {
setTimeout(function() {
while (true) { // continue to loop while wfOpen = true/1
if (wfOpen == 0) {
wfOpen = 1 ; // set global file lock to locked/true
console.log("writing to userdata.json") ;
writeToFile("userdata.json",userData) ;
}
}
},2000) ;
}
}
Предполагаемая 2-секундная задержка состоит в том, чтобы предотвратить резкий скачок процессора при ожидании освобождения файла... теоретически первая запись не должна занимать так много времени, и setTimeout фактически запускает условие, пока условие не начнет зацикливаться.