fs.readFile uses a buffer internally and will return the raw buffer if no encoding...
authorTim Caswell <tim@creationix.com>
Fri, 7 May 2010 05:03:43 +0000 (00:03 -0500)
committerRyan Dahl <ry@tinyclouds.org>
Fri, 7 May 2010 05:22:14 +0000 (22:22 -0700)
doc/api.markdown
lib/fs.js
lib/module.js
test/simple/test-ini.js

index 321edf7..2660f95 100644 (file)
@@ -1396,7 +1396,7 @@ is a string--what was read--and `bytesRead` is the number of bytes read.
 
 Synchronous version of `fs.read`. Returns an array `[data, bytesRead]`.
 
-### fs.readFile(filename, encoding='utf8', callback)
+### fs.readFile(filename, [encoding,] callback)
 
 Asynchronously reads the entire contents of a file. Example:
 
@@ -1408,6 +1408,8 @@ Asynchronously reads the entire contents of a file. Example:
 The callback is passed two arguments `(err, data)`, where `data` is the
 contents of the file.
 
+If no encoding is specified, then the raw buffer is returned.
+
 ### fs.readFileSync(filename, encoding='utf8')
 
 Synchronous version of `fs.readFile`. Returns the contents of the `filename`.
index abb0a5e..610d053 100644 (file)
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -1,5 +1,6 @@
 var sys = require('sys'),
-    events = require('events');
+    events = require('events'),
+    Buffer = require('buffer').Buffer;
 
 var binding = process.binding('fs');
 var fs = exports;
@@ -38,34 +39,39 @@ fs.Stats.prototype.isSocket = function () {
   return this._checkModeProperty(process.S_IFSOCK);
 };
 
-
-function readAll (fd, pos, content, encoding, callback) {
-  binding.read(fd, 4*1024, pos, encoding, function (err, chunk, bytesRead) {
-    if (err) {
-      if (callback) callback(err);
-    } else if (chunk) {
-      content += chunk;
-      pos += bytesRead;
-      readAll(fd, pos, content, encoding, callback);
-    } else {
-      binding.close(fd, function (err) {
-        if (callback) callback(err, content);
-      });
-    }
-  });
-}
-
 fs.readFile = function (path, encoding_, callback) {
-  var encoding = typeof(encoding_) == 'string' ? encoding_ : 'utf8';
+  var encoding = typeof(encoding_) == 'string' ? encoding_ : null;
   var callback_ = arguments[arguments.length - 1];
-  var callback = (typeof(callback_) == 'function' ? callback_ : null);
-  binding.open(path, process.O_RDONLY, 0666, function (err, fd) {
-    if (err) {
-      if (callback) callback(err);
-    } else {
-      // leave pos null to allow reads on unseekable devices
-      readAll(fd, null, "", encoding, callback);
-    }
+  var callback = (typeof(callback_) == 'function' ? callback_ : noop);
+  binding.stat(path, function (err, stat) {
+    if (err) { callback(err); return; }
+    binding.open(path, process.O_RDONLY, 0666, function (err, fd) {
+      if (err) { callback(err); return; }
+      var size = stat.size;
+      var buffer = new Buffer(size);
+      var offset = 0;
+      function doRead() {
+        // position is offset or null so we can read files on unseekable mediums
+        binding.read(fd, buffer, offset, size - offset, offset || null, function (err, amount) {
+          if (err) { callback(err); return; }
+          if (amount + offset < size) {
+            offset += amount;
+            doRead();
+            return;
+          }
+          if (encoding) {
+            try {
+              callback(null, buffer.toString(encoding));
+            } catch (err) {
+              callback(err);
+            }
+          } else {
+            callback(null, buffer);
+          }
+        });
+      }
+      doRead();
+    });
   });
 };
 
index 4c40f37..ae6c041 100644 (file)
@@ -339,7 +339,7 @@ function cat (id, callback) {
       }
     });
   } else {
-    requireNative('fs').readFile(id, callback);
+    requireNative('fs').readFile(id, 'utf8', callback);
   }
 }
 
index 489950d..2d2bb55 100644 (file)
@@ -8,7 +8,7 @@ debug("load fixtures/fixture.ini");
 
 p = path.join(fixturesDir, "fixture.ini");
 
-fs.readFile(p,function(err, data) {
+fs.readFile(p, 'utf8', function(err, data) {
   if (err) throw err;
 
   assert.equal(typeof parse, 'function');