After reading from position 0 (using fs.read), subsequence read with position null reads the incorrect data.
I would expect a read from position 0 followed by a read from null position to read from the next set of data per the documentation:
position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.
Save the following to a file and run it.
const fs = require('fs');
const assert = require('assert');
// change this to toggle failing vs passing behavior
const fail = true;
fs.open(__filename, 'r', (err, fd) => {
assert(!err);
const buff = new Buffer(4);
// this is the line that causes incorrect (unexpected?) behavior
// if 0 is passed to read, then the subsequent read with 'null'
// results in the wrong data being read
// when `null` is used I get `cons` followed by `t fs`
// when 0 is used first, I get `cons` followed by `cons`
fs.read(fd, buff, 0, 4, (fail) ? 0 : null, (err, bytes, buffer) => {
assert(!err);
assert.equal(buffer.toString(), 'cons');
console.log(buffer.toString());
fs.read(fd, buff, 0, 4, null, (err, bytes, buffer) => {
assert(!err);
assert.equal(buffer.toString(), 't fs');
console.log(buffer.toString());
});
});
});
What's happening here is that when you specify a position >= 0, pread() is used which does not modify the file pointer. When you pass a null position, read() is used which starts from the current file pointer.
Should the docs be updated to make this clear? Or would it be useful to
make the core implementation track the position internally and behave
appropriately when using a null read after a positional read?
On Friday, September 2, 2016, Brian White [email protected] wrote:
What's happening here is that when you specify a position >= 0, pread()
is used which does not modify the file pointer. When you pass a null
position, then the read occurs from the current file pointer.—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/nodejs/node/issues/8397#issuecomment-244518056, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAFLOKuSFGzvWXi7ZcI7Brjdfq31b3xRks5qmMmwgaJpZM4J0K7-
.
/cc @nodejs/collaborators
Should the docs be updated to make this clear?
The documentation for fs.read() seems clear enough to me:
`position` is an integer specifying where to begin reading from in the file.
If `position` is `null`, data will be read from the current file position.
Or would it be useful to make the core implementation track the position internally and behave appropriately when using a null read after a positional read?
Node.js has worked this way since forever so I don't think we would want to change that. It's covered by fs.createReadStream(path, { start: position }).
I should also note that if you need/want seeking support (to set the file pointer), there are always addons like fs-ext which provide fs.seek()/fs.seekSync(). Functions like that might be nice to have in core finally and should work on both *nix and Windows.
fs.seek()/fs.seekSync()
Those are really bad anti-patterns when reading or writing asynchronously because there is no consistent ordering of events. Consider:
fs.read(...);
fs.seekSync(...);
Does the seek happen before or after the read? No one knows. No one _can_ know.
@bnoordhuis Sure but if you call fs.seekSync() within the fs.read() callback (and before the next fs.read() in the original example), then it's not a problem.
What happens when you do:
fs.read(fd, buf1, 0, 4, null, ...);
fs.read(fd, buf2, 0, 4, null, ...);
? Is there a defined order in that scenario?
There isn't, you should use positional reads in that case.
The documentation for fs.read() seems clear enough to me:
Disagree. It is unclear for the original example I posted. If you do a read starting at position 0, you then think (rightfully so because nothing tells you otherwise) that the file position is now 0 + N bytes (4 in my example) and that a read using null will read from where the last read ended.
There isn't, you should use positional reads in that case.
I don't disagree that this is the better strategy (to be explicit in your read positions in these cases), which is why I think the documentation should make it clearer and guide the developer in understanding that position specified reading is disjoint from null position reading.
Documentation improvement PR would be welcome.
/cc @nodejs/documentation
If no one already reading this is inclined to submit a PR, then perhaps it makes sense to put a good first contribution label on the issue.
for me something has changed on 8.2 compared to 8.1, the documentation is confusing and https://github.com/nodejs/node/issues/8397#issuecomment-244518056 is correct
Most helpful comment
Disagree. It is unclear for the original example I posted. If you do a read starting at position 0, you then think (rightfully so because nothing tells you otherwise) that the file position is now 0 + N bytes (4 in my example) and that a read using
nullwill read from where the last read ended.I don't disagree that this is the better strategy (to be explicit in your read positions in these cases), which is why I think the documentation should make it clearer and guide the developer in understanding that position specified reading is disjoint from null position reading.