Как получить текущее смещение дескриптора потока или файла?

Есть ли в Node.js способ получить текущее смещение файлового дескриптора или потока? В настоящее время можно установить смещение файлового дескриптора, но кажется, нет никакого способа получить это.

В C получение смещения файлового потока осуществляется через ftell, а файл дескриптор через lseek(fd, 0, SEEK_CUR).

Пример

Если программе Node.js необходимо проверить наличие предшествующих данных в файле после его открытия в режиме добавления, в этом случае может помочь вызов ftell. Это можно сделать в C следующим образом:

#include <stdio.h>

int main() {
    FILE* f = fopen("test.txt", "a");
    fprintf(f, ftell(f) ? "Subsequent line\n" : "First line\n");
    fclose(f);
}

Запустив приведенную выше программу три раза, test.txt станет:

First line
Subsequent line
Subsequent line

предшествующий уровень техники

  • Проблема GitHub зарегистрирована для старой версии node. В обсуждении упоминаются bytesWritten и bytesEmitted, ни один из которых не эквивалентен ftell (в приведенном выше примере C байты, записанные при первом открытии файла, всегда равны 0). https://github.com/nodejs/node-v0.x-archive/issues/1527.
  • Пакет fs-ext NPM. Предоставляет низкоуровневый lseek для использования в Node.js. https://www.npmjs.com/package/fs-ext.

person mxxk    schedule 15.02.2020    source источник
comment
В node.js нет эквивалента ftell(). Общая идея заключается в том, что вы либо добавляете, либо указываете аргумент position с помощью fs.read() или fs.write(). Если вы хотите просто последовательно записать кучу данных, вы используете поток. Вы можете, конечно, получить текущую длину файла, а затем использовать position для чтения некоторого количества байтов с конца файла, если это то, что вы действительно пытаетесь сделать. Или просто используйте текущую длину файла, чтобы узнать, находитесь ли вы в начале файла после его открытия для добавления.   -  person jfriend00    schedule 15.02.2020


Ответы (2)


В node.js нет эквивалента ftell() или fseek(), и я не совсем понимаю, почему. Вместо этого вы обычно указываете позицию, в которой хотите читать или писать, всякий раз, когда вы читаете или пишете с помощью fs.read() или fs.write(). Если вы хотите просто записать кучу данных последовательно или вам нужна буферизованная запись, то вы, как правило, используете поток, который буферизует и упорядочивает для вас.

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

Вот код node.js, который делает что-то похожее на ваш код C.

const fs = require('fs');

async function myFunc() {
     let handle = await fs.promises.open("test.txt");
     try {
         const {size} = await handle.stat();
         await handle.appendFile(size ? "Subsequent line\n" : "First line\n");
     } finally {
         await handle.close();
     }
}

И, если вы вызовете это три раза так:

async function test() {
    await myFunc();
    await myFunc();
    await myFunc();
}

test();

Вы получите желаемые три строки в файле:

First line
Subsequent line
Subsequent line
person jfriend00    schedule 15.02.2020
comment
@mxxk - это ответ на ваш вопрос? - person jfriend00; 17.02.2020
comment
Да, @jfriend00, спасибо. :) В начале казалось, что в Node.js невозможно выполнить то, о чем я просил, но, возможно, это привлечет внимание будущих разработчиков, и однажды это станет возможным. - person mxxk; 19.02.2020

fs.read имеет параметр position.

fs.read(fd, buffer, offset, length, position, callback)

Здесь важен параметр position.

Будет ли этого достаточно для ваших нужд, если только я не смогу правильно понять ваш вопрос?

person rajesh pillai    schedule 15.02.2020