Как выполнить чтение с произвольным доступом из (больших) файлов с помощью node.js?

Я что-то упустил или в стандартном модуле файлового ввода-вывода node.js отсутствуют аналоги обычных методов произвольного доступа к файлам?

  • seek() / fseek()
  • tell() / ftell()

Как читать случайные записи фиксированного размера из больших файлов в узле без них?


person hippietrail    schedule 18.12.2012    source источник


Ответы (4)


tell нет, но довольно редко вы еще не знаете, в какой позиции вы находитесь в файле, или не имеете возможности отслеживать себя.

seek выставляется косвенно через аргумент position fs.read и fs.write. При задании аргумент будет искать это место перед выполнением своей операции, и если null, он будет использовать любую предыдущую позицию, которую он имел.

person loganfsmyth    schedule 24.12.2012
comment
Времена, когда я использую tell, в основном, когда я читаю текст в независимом от платформы коде построчно, строки которого могут заканчиваться на \n, \r (больше не распространено) или \r\n. Тем не менее, конечно, все еще возможно отслеживать позицию без tell. - person hippietrail; 24.12.2012
comment
Для всех, кто может читать эту ветку, я пропустил параметр position, потому что при чтении документов мне удалось объединить его с параметром offset, который представляет собой смещение от начала буфера, в который вы хотите считывать данные. . - person hippietrail; 24.12.2012
comment
Это отлично работает для чтения записей из двоичных файлов, но мне также нужно читать строки текста из переданных смещений файлов. Оказывается, очень трудно прочитать одну строку текста с использованием fs.read из-за природы Buffer и необходимости преобразования такого текста в кодированный текст, такой как UTF-8. Очевидные способы приводят к неработающим символам, поскольку UTF-8 включает многобайтовые символы. ReadableStream обрабатывает многобайтовые символы, но не позволяет свободно искать. Я не уверен, что есть какая-либо библиотека, которая позволяет сочетать произвольный доступ и чтение строк. - person hippietrail; 02.01.2013
comment
@hippietrail Эти двое, к сожалению, немного расходятся друг с другом. Это не очень распространенная проблема. Тем не менее, пожалуйста, создайте новый вопрос, если вы хотите получить ответы на этот вопрос. Чтение строк из случайных позиций здесь не зависит от вашего исходного вопроса. - person loganfsmyth; 02.01.2013
comment
Спасибо @loganfsmyth, я задам конкретный вопрос. Я просто хотел, чтобы мои мысли были связаны здесь, прежде чем мой интернет-кредит закончился прошлой ночью. Хотя мой вариант использования (индексация смещений в очень больших текстовых файлах — XML-дампы Википедии) не является обычным явлением, я реализовал его раньше на C, Perl и даже JavaScript в плагине FireFox, поэтому я был удивлен, что это было так сложно в узле, учитывая, сколько лучший узел в том, что эти среды по-разному. - person hippietrail; 03.01.2013

node не имеет их встроенных, самое близкое, что вы можете получить, это использовать fs.createReadStream с параметром start, чтобы начать чтение со смещения (передайте существующий fd, чтобы избежать повторного открытия файла).

http://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

person yiding    schedule 18.12.2012
comment
Если это не окажется медленным, это кажется идеальным решением. Это может зависеть от стоимости создания ReadStream из fd. - person hippietrail; 20.12.2012
comment
Нужно ли мне также передавать один и тот же параметр пути каждый раз, когда я снова вызываю createReadStream()? path является обязательным, в то время как fd является необязательным, и документы не ясны. - person hippietrail; 22.12.2012
comment
хм ... вы пробовали передать null для пути, хотя он говорит, что это необходимо? иначе я бы просто прошел по тому же пути. - person yiding; 23.12.2012
comment
Да, с тех пор я попробовал это, и требуемый path игнорируется независимо от того, что это такое, если вы также указываете необязательный fd. Это не гарантируется явно в документации или указано в источнике. Также я не могу найти ничего авторитетного, ища форумы. Я ненавижу полагаться на поведение, которое не задокументировано, даже если оно подкреплено здравым смыслом. Я мог бы найти способ спросить официально. Спасибо. - person hippietrail; 23.12.2012
comment
Я столкнулся с проблемами при попытке использовать это несколько раз каждый раз, когда я хочу прочитать из некоторой позиции в одном и том же файле: createReadStream несколько раз на одном и том же фд - person hippietrail; 24.12.2012

Я предполагаю, что createReadStream снова и снова создает новый файловый дескриптор. Я предпочитаю версию синхронизации:

function FileBuffer(path) {
const fd = fs.openSync(path, 'r');

function slice(start, end) {
    const chunkSize = end - start;
    const buffer = new Buffer(chunkSize);

    fs.readSync(fd, buffer, 0, chunkSize, start);

    return buffer;
}

function close() {
    fs.close(fd);
}

return {
    slice,
    close
}

}

person Suprido    schedule 18.10.2016

Использовать это:

fs.open(path, flags[, mode], callback)

Тогда это:

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

Прочитайте это для деталей:

https://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback

person Community    schedule 24.08.2017