2017-02-02 9 views
2

ホームネットワークで使用するファイル共有アプリケーションを作成しました。 GoogleドライブやDropboxのウェブインターフェースと似ていますが、ファイルサイズの上限やセキュリティはありません。単純なNode.jsプログラムはすべてのシステムメモリを奪い、永遠にXMLHttpRequestファイルバッファをディスクに書き出します

LAN経由で接続されている他のコンピュータから小さなファイルをすぐに転送するときにはうまく動作しますが、2GBファイルでテストすると奇妙なことが起こります。

プログレスバーが50%になってから切断するまでに約4時間かかりました。また、Nodeが使用しているメモリの量を見てみましょう。

Node memory hog

は、低オフを開始し、その後、ダンプと再起動、何回か分、13ギガバイトと同じくらいまでの道を構築します。

ファイルは、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); 

そしてreq.files.fileを取り、ディスクに保存するfs.writeFileに直接渡しExpressを使用して、非常に単純なハンドラがあります、サーバー側で。 ( 'req.files.file'はconsole.logによると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です。

どこが間違っていますか?この問題にどうやってアプローチするのですか?

+0

どのようなミドルウェアを使用してアップロードを処理しますか? 'multer'?初期化を共有してください。 –

+0

@ SergeyLapin私の間違い。その情報を含める必要があります。私はexpress-fileuploadを使用しています。私は私の質問を更新しました。 – JSideris

+0

ありがとうございます。私はこのプロジェクトをGitHub [here](https://github.com/JSideris/sinc)で公開しています。 – JSideris

答えて

1

ルック

これはまともな短いチュートリアルでした。ファイルが到着すると、着信ストリームを受け取り、それをBuffer、すなわちメモリに入れ始める。 これが完了すると、writeFile経由でこのメモリバッファをディスクに書き込みます。

express-fileuploadには、ファイルをメモリに格納しないようにするオプションはありません。 multerを使用してDiskStorageオプションを使用することを検討してください:docs

+0

[これは私が見たいものです](http://i.imgur.com/IDfvxX8.png)。 – JSideris

+0

おめでとう! –

1

大きなファイルの場合は、writeFileの代わりにwriteStreamを使用してください。 writeFileを使用すると、ファイル全体をメモリに保存する必要があります。そのため、メモリが大量に消費されます。 http://joshondesign.com/2014/06/25/nodestreamsareawesome

そしてNode.jsのは、それが同様にドキュメントのしている:express-fileupload sourcehttps://nodejs.org/api/fs.html#fs_class_fs_writestream

+0

'writeFile'が実行される瞬間には、巨大な' Buffer'インスタンスへの参照があるので、すべてのデータはすでにメモリにあります。 –

+0

@SergeyLapinそれは?これらのバッファはどのように機能しますか?私は過去にHTTPバッファを扱っていませんでしたが、バッファ全体が読み込まれるまでクライアントからサーバーへの永続ストリームと仮定しています。私のメモリ使用量がチャート(13GB)から外れている理由を説明していませんが、私はこれを撃つでしょう。 – JSideris

+0

@JSideris元の投稿への私のコメントにお答えできますか? –

関連する問題