【问题标题】:How do you upload, stream, and hash a file's contents in Node.js?如何在 Node.js 中上传、流式传输和散列文件内容?
【发布时间】:2011-10-05 05:15:49
【问题描述】:

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

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

这是我想做的 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,但没有一个真正读写数据。

【问题讨论】:

标签: node.js upload express


【解决方案1】:

这里是咖啡脚本的所有荣耀。

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

我没有选择将哈希计算变成强大的(这可能会更有效但更复杂),而是选择从其临时位置重新读取文件并对其进行哈希处理。然后,我没有像在其他示例中那样将其抽出,而是将临时文件重命名到其新位置。

【讨论】:

    【解决方案2】:

    您可以像这样保存文件:

    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('....');
            }
        });
    
    });
    

    【讨论】:

    • 接近了,但这仍然没有根据文件的内容命名文件。不过我想我已经弄清楚了。
    猜你喜欢
    • 2018-01-28
    • 2017-05-09
    • 1970-01-01
    • 2014-04-08
    • 2012-12-08
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多