1

On a web-application that I am working on, users can upload a PDF file. I would like to read this PDF file to a buffer of bytes, which I can pass on to my database to save it as a BLOB. I am doing this in Node, using the Express framework.

Currently, I have the following:

Upload form:

<form id='uploadForm' method='post' enctype='multipart/form-data'>
    <div class='form-group'>
        <div class='form-inline'>
            <label for='file'>File:</label>
            <input type='file' name='file'>
        </div>
    </div>
    <!--- some other fields --->
</form>

Server side:

router.post('/', function(req, res) {
    var file = req.files.file;
    var path = file.path;
    var fsiz = file.size;
    var buffer = new Buffer(fsiz);

    fs.read(file, buffer, 0, fsiz, 0, function (err, bytesRead, buffer) {
        console.log(err);
        console.log(bytesRead);
        console.log(buffer);
    });

});

This gives me a Bad argument error on the fs.read function call. What is wrong and how can I fix it?

JNevens
  • 11,202
  • 9
  • 46
  • 72

1 Answers1

2

fs.read()'s first argument is supposed to be a file descriptor object, as returned by fs.open().

You can either first call fs.open(), or else use fs.readFile(), which takes a path:

router.post('/', function(req, res) {
    var file = req.files.file;
    var path = file.path;
    var fsiz = file.size;
    var buffer = new Buffer(fsiz);

    fs.open(path, 'r', function(err, fd) {

        fs.read(fd, buffer, 0, fsiz, 0, function (err, bytesRead, buffer) {
            console.log(err);
            console.log(bytesRead);
            console.log(buffer);
        });

    });

});
router.post('/', function(req, res) {
    var file = req.files.file;
    var path = file.path;
    var fsiz = file.size;
    var buffer = new Buffer(fsiz);

    fs.readFile(path, function (err, data) {
        console.log(err);
        console.log(data);
    });

});
Scimonster
  • 32,893
  • 9
  • 77
  • 89
  • But the OP wants to save files **to** the filesystem, not read from it. – Robert Rossmann Mar 29 '15 at 14:01
  • No, he wants to get it as a **Buffer**, and write *that* to a *database*. – Scimonster Mar 29 '15 at 14:02
  • I believe the server side code example clearly demonstrates the OP's intention, especially this line: `var file = req.files.file`. The file comes directly from the user - there is no mention of storing this file on the fs first and then reading it. – Robert Rossmann Mar 29 '15 at 14:04
  • @RobertRossmann And since the file can't just float around, it *does* get saved to the filesystem, in temporary storage. See http://expressjs.com/3x/api.html#req.files for how `req.files` works. – Scimonster Mar 29 '15 at 14:06
  • You are right. [this](http://www.hacksparrow.com/handle-file-uploads-in-express-node-js.html) helped me understand. Previously, I used body parsers that did not save the files to the disk but rather provided me with a readable stream that I had to consume in my route. `bodyParser` seems to work differently. – Robert Rossmann Mar 29 '15 at 14:12
  • @Scimonster Is there any way to read an entire file as bytes or hex characters? This question and the documentation (of ExpressJS and NodeJS) don't have a way to parse an entire file thru a JS or TS script. – Joachim Rives Nov 09 '21 at 03:30