简单的Node.js程序占用所有系统内存并永远将XMLHttpRequest文件缓冲区写入磁盘

时间:2017-02-02 09:32:25

标签: javascript node.js express buffer

我已创建了一个可在家庭网络上使用的文件共享应用。它类似于Google云端硬盘或Dropbox的网络界面,但没有任何文件大小上限,也没有任何安全性。

当从通过LAN连接的其他计算机立即传输小文件时,它可以很好地工作,但是在2GB文件上测试它时发生了奇怪的事情。

在我将其切断之前,进度条花了大约四个小时达到50%。另外,看看Node正在使用多少内存。

Node memory hog

它将从低速开始并建立高达13GB的速度,然后转储并重新启动,每分钟几次。

使用XMLHttpRequest从浏览器界面上传文件。这是前端代码的重要组成部分。

var formData = new FormData();
var file = document.getElementById("fileinput").files[0];
formData.append("file", file);

var xhr = new XMLHttpRequest();
xhr.open("post", "/fileupload", true);
xhr.send(formData);

在服务器端有一个非常简单的使用express的处理程序,它接受req.files.file并将其直接传递给fs.writeFile以将其保存到磁盘。 (根据console.log,'req.files.file'似乎是Buffer类型,显然可以是piped right onto disk)。

var express = require("express");
var fileUpload = require("express-fileupload");
var app = express();
app.use(express.static("public"));
app.use(fileUpload());
var fs = require("fs");

app.post('/fileupload', function(req, res) {
    if(req.files && req.files.file){
        var file = req.files.file;
        fs.writeFile("./public/shared/" + file.name, file.data, "binary", function(err) {
            if(err) {
                res.send(err);
                return;
            }
            res.send("File uploaded successfully.");
        }); 
    }
    else{
        res.send("No file was uploaded.");
        return;
    }
});

我正在使用express-fileupload来处理上传。

两台计算机都在运行Windows。发送计算机正在使用Chrome。节点版本为7.5.0。

我哪里错了?我该如何处理这个问题?

2 个答案:

答案 0 :(得分:1)

对于大文件,您应该使用writeStream而不是writeFile。 当你使用writeFile时,整个文件必须保存在内存中,因此占用大量内存。

这是一个不错的简短教程:http://joshondesign.com/2014/06/25/nodestreamsareawesome

node.js也有它的文档: https://nodejs.org/api/fs.html#fs_class_fs_writestream

答案 1 :(得分:1)

看看express-fileupload source。当文件到达时,它接收一个输入流并开始将其放入Buffer,即进入内存。 完成后,您可以通过writeFile将此内存缓冲区写入磁盘。

express-fileupload无法避免将文件存储在内存中。考虑将multerDiskStorage提供的/选项一起使用:docs