-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
fs: .writeFile(filehandle, ...)
behavior differs from the documented one in all its variants
#22554
Comments
@nodejs/fs |
It seems the
const fsPromises = require('fs').promises;
const fileName = 'test.txt';
(async function main() {
try {
await fsPromises.writeFile(fileName, '123');
await fsPromises.writeFile(fileName, '0');
console.log(await fsPromises.readFile(fileName, 'utf8'));
await fsPromises.unlink(fileName);
const filehandle = await fsPromises.open(fileName, 'w');
await fsPromises.writeFile(filehandle, '123');
await fsPromises.writeFile(filehandle, '0');
await filehandle.close();
console.log(await fsPromises.readFile(fileName, 'utf8'));
await fsPromises.unlink(fileName);
} catch (err) {
console.error(err);
}
})();
const fsPromises = require('fs').promises;
const fileName = 'test.txt';
(async function main() {
try {
const filehandle = await fsPromises.open(fileName, 'w');
await filehandle.writeFile('123');
await filehandle.writeFile('0');
await filehandle.close();
console.log(await fsPromises.readFile(fileName, 'utf8'));
await fsPromises.unlink(fileName);
} catch (err) {
console.error(err);
}
})();
|
cc @jasnell re |
Maybe the easiest solution would be to call |
fs.writeFile[Sync]()
description ambiguity.writeFile(filehandle, ...)
behavior differs from the documented one in all its variants
Adding v11 milestone to be on the safe side. Feel free to remove if we should document these unexpectednesses rather than fix them. |
@nodejs/fs if we want to fix this behavior in a semver-major way, we have just a week till v11 semver-major cut-off (October 2nd). |
diff --git a/lib/fs.js b/lib/fs.js
index 3302cfe0bf..2fe9ec5bbd 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -1193,7 +1193,17 @@ function writeFile(path, data, options, callback) {
data : Buffer.from('' + data, options.encoding || 'utf8');
const position = /a/.test(flag) ? null : 0;
- writeAll(fd, isUserFd, buffer, 0, buffer.byteLength, position, callback);
+ if (isUserFd && !/a/.test(flag)) {
+ ftruncate(fd, (err) => {
+ if (err) {
+ return callback(err);
+ }
+ writeAll(
+ fd, isUserFd, buffer, 0, buffer.byteLength, position, callback);
+ });
+ } else {
+ writeAll(fd, isUserFd, buffer, 0, buffer.byteLength, position, callback);
+ }
}
}
@@ -1203,6 +1213,9 @@ function writeFileSync(path, data, options) {
const isUserFd = isFd(path); // file descriptor ownership
const fd = isUserFd ? path : fs.openSync(path, flag, options.mode);
+ if (isUserFd && !/a/.test(flag)) {
+ ftruncateSync(fd);
+ }
if (!isArrayBufferView(data)) {
data = Buffer.from('' + data, options.encoding || 'utf8'); This rough attempt seems to fix it and all our current tests pass. |
Simple Reproduction of the Bug ```js 'use strict'; const assert = require('assert'); const fs = require('fs'); const fileName = 'test.txt'; fs.writeFileSync(fileName, '123'); fs.writeFileSync(fileName, '0'); const result1 = fs.readFileSync(fileName, 'utf8'); fs.unlinkSync(fileName); const fd = fs.openSync(fileName, 'w'); fs.writeFileSync(fd, '123'); fs.writeFileSync(fd, '0'); fs.closeSync(fd); const result2 = fs.readFileSync(fileName, 'utf8'); fs.unlinkSync(fileName); assert.deepStrictEqual(result2, result1); // + expected - actual // //- '023' //+ '0' ``` Fixes: nodejs#22554
This will need to land by Saturday if it's going to make the 11.0.0 milestone. |
@vsemozhetbyt Can this be closed now, as we concluded #23433 and documentation update is pending in #25080? |
Thank you for handling this. |
Currently, the
fs.writeFile[Sync]()
description states:However, this is only true if the first argument is a filename. If it is a file descriptor, the file content is not truncated (as somebody may expect) and a new data is merged from the
0
position into the old data.fs.readFileSync()
behavior:fs.writeFile()
behavior:If this is intended behavior, should we make the description more accurate?
The text was updated successfully, but these errors were encountered: