How to get current offset of stream or file descriptor?

淺唱寂寞╮ 提交于 2021-01-05 13:00:12

问题


In Node.js, is there any way of getting the current offset of a file descriptor or stream? Presently, it is possible to set the offset of a file descriptor, but there seems to be no way to get it.

In C, getting the offset of a file stream is done via ftell, and a file descriptor via lseek(fd, 0, SEEK_CUR).

Example

If a Node.js program needs to check whether there is prior data in a file after opening it in append mode, a call to ftell would help in this case. This can be done in C as follows:

#include <stdio.h>

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

Running the above program three times, test.txt becomes:

First line
Subsequent line
Subsequent line

Prior Art

  • GitHub issue filed for old version of node. The discussion mentions bytesWritten and bytesEmitted, neither of which is equivalent to ftell (in the above C example, the bytes written when the file is first opened is always 0). https://github.com/nodejs/node-v0.x-archive/issues/1527.
  • The fs-ext NPM package. Exposes the low-level lseek for use in Node.js. https://www.npmjs.com/package/fs-ext.

回答1:


There is no equivalent to ftell() or fseek() in node.js and I'm not really sure why. Instead, you generally specify the position you want to read or write at whenever you read or write with fs.read() or fs.write(). If you want to just write a bunch of data sequentially or you want buffered writing, then you would more typically use a stream which buffers and sequences for you.

Instead, if you want to know where data will be appended, you can fetch the current file length and then use that current file length to know if you're at the beginning of the file after opening it for appending.

Here's node.js code that does something similar to your C code.

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();
     }
}

And, if you call this three times like this:

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

test();

You will get your desired three lines in the file:

First line
Subsequent line
Subsequent line



回答2:


The fs.read has position parameter.

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

The position parameter is important here.

Will this suffice your need unless I am not able to understand your question correctly?



来源:https://stackoverflow.com/questions/60237517/how-to-get-current-offset-of-stream-or-file-descriptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!