Каков наилучший способ сохранить файл открытым для чтения / записи? - PullRequest
0 голосов
/ 24 января 2020

У меня есть локальный JSON файл, который я намереваюсь читать / записывать из NodeJS электронного приложения. Я не уверен, но я считаю, что вместо использования readFile () и writeFile () я должен получить FileHandle, чтобы избежать нескольких действий открытия и закрытия.

Поэтому я попытался получить FileHandle от fs .promises.open (), но проблема в том, что я не могу получить FileHandle из существующего файла без его усечения и очистить его до 0.

const { resolve } = require('path');
const fsPromises = require('fs').promises;

function init() {
  // Save table name
  this.path = resolve(__dirname, '..', 'data', `test.json`);

  // Create/Open the json file
  fsPromises
    .open(this.path, 'wx+')
    .then(fileHandle => {
      // Grab file handle if the file don't exists 
      // because of the flag 'wx+'
      this.fh = fileHandle;
    })
    .catch(err => {
      if (err.code === 'EEXIST') {
        // File exists
      }

    });
}

Я что-то не так делаю? Есть ли лучшие способы сделать это?


Ссылки:
https://nodejs.org/api/fs.html#fs_fspromises_open_path_flags_mode
https://nodejs.org/api/fs.html#fs_file_system_flags

1 Ответ

0 голосов
/ 24 января 2020

Поскольку JSON - это текстовый формат, который необходимо читать или записывать одновременно, и его нельзя легко изменить или добавить на месте, вам придется прочитать весь файл или записать весь файл сразу.

Итак, самым простым вариантом будет просто использовать fs.promises.readFile() и fs.promises.writeFile() и позволить библиотеке открыть файл, прочитать / записать его и закрыть файл. Открытие и закрытие файла в современной ОС использует преимущества кэширования диска, поэтому, если вы открываете файл, который вы только что открыли, не долго go, это не будет медленной операцией. Кроме того, поскольку nodejs выполняет эти операции во вторичных потоках в libuv, он также не блокирует основной поток nodejs, поэтому, как правило, это не проблема производительности вашего сервера.

Если вы действительно хотели откройте файл один раз и удерживайте его открытым, вы бы открыли его для чтения и записи, используя флаг r+, например:

const fileHandle = await fsPromises.open(this.path, 'r+');

Чтение всего файла будет простым, поскольку новый объект fileHandle имеет .readFile() method.

 const text = await fileHandle.readFile({encoding 'utf8'});

Для записи всего файла из открытого дескриптора файла, вам нужно будет обрезать файл, затем записать свои байты, затем flu sh буфер записи, чтобы обеспечить последний бит данные попадают на диск и не помещаются в буфер.

await fileHandle.truncate(0);                         // clear previous contents
let {bytesWritten} = await fileHandle.write(mybuffer, 0, someLength, 0);   // write new data
assert(bytesWritten === someLength);
await fileHandle.sync();                              // flush buffering to disk
...