如何在Node.js中上传,流式传输和散列文件的内容?

时间:2011-10-05 05:15:50

标签: node.js upload express

我想在我的服务器上传文件并根据其内容命名。这应该很简单(它在python中),但我很难弄清楚如何在Node.js中做到这一点。

我正在使用express和connect-form,really just uses formidable。我还看到该节点有一个名为crypto的库,它与python的hashlib非常相似。现在我只需要了解如何流式传输临时文件connect-form给我并哈希它。

这是我想要做的Python / Flask(ish)实现。

import hashlib
from Flask import request

def upload():
  file = request.files['file']
  hash = hashlib.sha256()
  name, ext = file.filename.rsplit('.', 1)
  try:
    for chunk in file.chunks()
      hash.update(chunk)
  finally:
    file.seek(0)
    new_name = "%s.%s" % (hash.hexdigest(),ext)
    file.save(os.path.join(UPLOAD_DIR, new_name))

我见过很多这些toy answers that just print out the file's name,但实际上并没有读取和写入数据。

2 个答案:

答案 0 :(得分:3)

这里充满了咖啡脚本。

app.post '/upload', (request, response, next) ->
    request.form.complete (error, fields, files) ->
        if error
            next error
        else
            file = files.file
            [kind, extension] = file.type.split '/'
            hash = crypto.createHash 'sha256'
            stream = fs.createReadStream file.path,
                encoding:'binary'
            stream.addListener 'data', (chunk) ->
                hash.update chunk
            stream.addListener 'close', ->
                digest = hash.digest 'hex'
                new_filename = "#{digest}.#{extension}"
                new_path = "#{UPLOAD_DIR}/#{new_filename}"
                fs.rename file.path, new_path
                response.end new_filename

我没有将哈希计算破解成强大的,这可能更有效但更复杂,我选择从其临时位置重新读取文件并散列。然后,不像其他示例中那样抽取它,我只是将临时文件重命名为新位置。

答案 1 :(得分:1)

你可以保存这样的文件:

var fs = require('fs'),
    util = require('util'),
    crypto = require('crypto');

// ...

req.form.complete(function (err, fields, files) {

    // ...

    var ext = files['content[media]']['filename'].split('.');
        ext = ext[ext.length-1];
        ext = ext.toLowerCase();

    var newFileName = req['connection']['remoteAddress'] + req['connection']['remotePort'] + Date.now();
    newFileName = crypto.createHash('md5').update(newFileName).digest("hex");
    newFileName += '.' + ext;

    var is = fs.createReadStream(files['content[media]']['path']);
    var os = fs.createWriteStream(app.set('dataDir') + '/' + newFileName);

    // copy file to public folder
    util.pump(is, os, function(error) {
        if (error) {
            console.log("Error copying file to public ... " + error);

            res.redirect("back");
            return;
        }
        else {
            // delete temp file
            fs.unlinkSync(files['content[media]']['path']);

            res.redirect('....');
        }
    });

});