-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
readFile(fd) does not read the whole file (at least on Windows, possibly other platforms) #9671
Comments
It seems sparseness is not the cause. This is also throws (Node.js 7.1.0 on Windows 7 x64): var fs = require('fs');
var buffer = Buffer.alloc(8192);
var path = 'test-read-file';
var fd = fs.openSync(path, 'w+');
console.log('created or truncated, file size is now: ' + fs.fstatSync(fd).size);
console.log('writing 8192 bytes at offset ' + (0));
fs.writeSync(fd, Buffer.alloc(8192, 1), 0, 8192, 0);
console.log('file size is now: ' + fs.fstatSync(fd).size + '\r\n');
console.log('reading 8192 bytes using readSync()...');
var bytesRead = fs.readSync(fd, buffer, 0, 8192, 0);
if (bytesRead !== 8192) {
throw new Error('readSync() read ' + bytesRead + ' bytes');
} else {
console.log('readSync() read ' + bytesRead + ' bytes');
}
console.log('\r\nreading entire file using readFileSync()...');
var result = fs.readFileSync(fd);
if (result.length !== buffer.length) {
throw new Error('readFileSync returned a buffer with length ' + result.length);
} else {
console.log('readFileSync returned a buffer with length ' + result.length);
}
fs.closeSync(fd);
fs.unlinkSync(path);
console.log('\r\nPASSED'); |
It seems the cause is this: after // ...
console.log('reading 8191 bytes using readSync()...');
var bytesRead = fs.readSync(fd, buffer, 0, 8191, 0);
if (bytesRead !== 8191) {
throw new Error('readSync() read ' + bytesRead + ' bytes');
} else {
console.log('readSync() read ' + bytesRead + ' bytes');
}
// ...
Or in this case: // ...
console.log('reading 1 bytes using readSync()...');
var bytesRead = fs.readSync(fd, buffer, 0, 1, 0);
if (bytesRead !== 1) {
throw new Error('readSync() read ' + bytesRead + ' bytes');
} else {
console.log('readSync() read ' + bytesRead + ' bytes');
}
// ...
While if you use path string instead of // ...
var result = fs.readFileSync('test-sparse-read-file');
// ...
|
So the bug seems to be this one: |
Your script at #9671 (comment) passes on OS X, I don't have a Windows to try on. The function used to read files is I wonder, could uv's emulation of |
@sam-github I'll try, but let's simplify it first. This throws with Node.js 7.1.0 on Windows 7 x64: 'use strict';
const assert = require('assert');
const fs = require('fs');
const filleLength = 2;
const path = 'test-read-file';
const fd = fs.openSync(path, 'w+');
fs.writeSync(fd, Buffer.alloc(filleLength, 1), 0, filleLength, 0);
assert.strictEqual(fs.readFileSync(fd).length, filleLength);
Does it throw on Linux or Mac? |
Does not throw on unixen, as expected. Please remove the complex ball of js code that is |
So, if I get it right, with some corrections ( const assert = require('assert');
const fs = require('fs');
const filleLength = 2;
const path = 'test-read-file';
const fd = fs.openSync(path, 'w+');
fs.writeSync(fd, Buffer.alloc(filleLength, 1), 0, filleLength, 0);
assert.equal(filleLength, fs.readSync(fd, Buffer.alloc(filleLength, 1), 0, filleLength, 0)); It passes with Node.js 7.1.0 on Windows 7 x64. But this throws (nota bene const assert = require('assert');
const fs = require('fs');
const filleLength = 2;
const path = 'test-read-file';
const fd = fs.openSync(path, 'w+');
fs.writeSync(fd, Buffer.alloc(filleLength, 1), 0, filleLength, 0);
assert.equal(filleLength, fs.readSync(fd, Buffer.alloc(filleLength, 1), 0, filleLength, null));
Does this last code throw on Linux or Mac? It should, if I get it right. So maybe we should return to previous one. |
/to @nodejs/platform-windows |
Are there any |
It seems I've found the cause.
Compare fs.readSync = function(fd, buffer, offset, length, position) { and the call from bytesRead = fs.readSync(fd, buffer, pos, len); so position is allways |
@seishun @vsemozhetbyt got time to PR a fix + regression test? It would be great if you did. |
I'm afraid I have not the experience and knowledge required to edit the core and to make appropriate tests( |
@sam-github I see. I guess the documentation could be clearer on this. So the issue is that |
@seishun No, it appears from #9671 (comment) that the issue is that the position is not actually being specified to fs.read in readFileSync, leading to the current OS maintained offset being used. The OS offset is correct only under assumption that readFile was called with a path, opened a new file, so started from offset of Or so it is described above, I might have time next week to look at this if nobody else grabs it. |
Sorry for my previous deleted comment, I do can reproduce the failure with the const assert = require('assert');
const fs = require('fs');
const filleLength = 2;
const path = 'test-read-file';
const fd = fs.openSync(path, 'w+');
fs.writeSync(fd, Buffer.alloc(filleLength, 1), 0, filleLength, 0);
fs.readFile(fd, (err, buf) => {
if (err) throw err;
assert.strictEqual(buf.length, filleLength);
});
I'll try to find the cause. |
It seems there's a bug on Linux too: 'use strict';
const assert = require('assert');
const fs = require('fs');
const fileLength = 2;
const path = 'test-read-file';
const fd = fs.openSync(path, 'w+');
fs.writeSync(fd, Buffer.alloc(fileLength, 1), 0, fileLength); // note: not specifying offset
assert.strictEqual(fs.readFileSync(fd).length, fileLength);
|
I've tried to track down binding.read(this.fd, buffer, offset, length, -1, req); Somehow position is |
@vsemozhetbyt |
@seishun So, if |
It seems so. At any rate, tests pass with |
It would previously read from the current file position, which can be non-zero if the `fd` has been read from or written to. This contradicts the documentation which states that it "reads the entire contents of a file". PR-URL: nodejs#9699 Fixes: nodejs#9671 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Sam Roberts <[email protected]>
It would previously read from the current file position, which can be non-zero if the `fd` has been read from or written to. This contradicts the documentation which states that it "reads the entire contents of a file". PR-URL: nodejs#9699 Fixes: nodejs#9671 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Sam Roberts <[email protected]>
Um how did this get closed? |
File read or write from specified position will move file pointer on Windows but not on POSIX. This makes Windows behave as other supported platforms. Ref: nodejs/node#9671
File read or write from specified position will move file pointer on Windows but not on POSIX. This makes Windows behave as other supported platforms. Ref: nodejs/node#9671 PR-URL: #1357 Reviewed-By: Santiago Gimeno <[email protected]> Reviewed-By: Saúl Ibarra Corretgé <[email protected]>
This should remain open? |
The provided test case no longer reproduces on master, so closing. |
I wrote a small test that passes on Mac and Linux but throws on Windows:
Linux:
Windows:
The test shows that the problem does not appear to be with read() but only with readFileSync().
readFile() has the same issue.
The text was updated successfully, but these errors were encountered: