From 589e27948ba3a08651514f7d88574ad9f5200969 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sat, 13 Nov 2010 20:12:47 -0800 Subject: [PATCH] writeFile fixes writeFileSync could exhibit pathological behavior when a buffer could not be written to the file in a single write() call. Also, writeFile was not quite as optimized as it could be. --- lib/fs.js | 22 ++++++++++------- test/simple/test-fs-write-file-buffer.js | 30 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 test/simple/test-fs-write-file-buffer.js diff --git a/lib/fs.js b/lib/fs.js index ecbe0139e0..3afe6e93dc 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -388,17 +388,18 @@ fs.chownSync = function(path, uid, gid) { return binding.chown(path, uid, gid); }; -function writeAll (fd, buffer, callback) { - fs.write(fd, buffer, 0, buffer.length, null, function (writeErr, written) { +function writeAll (fd, buffer, offset, length, callback) { + // write(fd, buffer, offset, length, position, callback) + fs.write(fd, buffer, offset, length, offset, function (writeErr, written) { if (writeErr) { fs.close(fd, function () { if (callback) callback(writeErr); }); } else { - if (written === buffer.length) { + if (written === length) { fs.close(fd, callback); } else { - writeAll(fd, buffer.slice(written), callback); + writeAll(fd, buffer, offset+written, length-written, callback); } } }); @@ -413,18 +414,21 @@ fs.writeFile = function (path, data, encoding_, callback) { if (callback) callback(openErr); } else { var buffer = Buffer.isBuffer(data) ? data : new Buffer(data, encoding); - writeAll(fd, buffer, callback); + writeAll(fd, buffer, 0, buffer.length, callback); } }); }; fs.writeFileSync = function (path, data, encoding) { - encoding = encoding || "utf8"; // default to utf8 var fd = fs.openSync(path, "w"); + if (!Buffer.isBuffer(data)) { + data = new Buffer(data, encoding || "utf8") + } var written = 0; - while (written < data.length) { - written += fs.writeSync(fd, data, 0, encoding); - data = data.slice(written); + var length = data.length; + //writeSync(fd, buffer, offset, length, position) + while (written < length) { + written += fs.writeSync(fd, data, written, length-written, written); } fs.closeSync(fd); }; diff --git a/test/simple/test-fs-write-file-buffer.js b/test/simple/test-fs-write-file-buffer.js new file mode 100644 index 0000000000..6d3c557a0d --- /dev/null +++ b/test/simple/test-fs-write-file-buffer.js @@ -0,0 +1,30 @@ +var common = require('../common'); +var join = require('path').join; +var util = require('util'); +var fs = require('fs'); + +var data = [ +'/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcH', +'Bw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/', +'2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e', +'Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAQABADASIAAhEBAxEB/8QA', +'HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF', +'BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK', +'FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1', +'dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG', +'x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEB', +'AQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAEC', +'AxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRom', +'JygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE', +'hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU', +'1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDhfBUFl/wk', +'OmPqKJJZw3aiZFBw4z93jnkkc9u9dj8XLfSI/EBt7DTo7ea2Ox5YXVo5FC7g', +'Tjq24nJPXNVtO0KATRvNHCIg3zoWJWQHqp+o4pun+EtJ0zxBq8mnLJa2d1L5', +'0NvnKRjJBUE5PAx3NYxxUY0pRtvYHSc5Ka2X9d7H/9k=']; + +data = data.join('\n'); + +var buf = new Buffer(data, 'base64'); +fs.writeFileSync(join(common.tmpDir, 'test.jpg'), buf); + +util.log('Done!');