2

私の隕石アプリでは、サーバーはファイルをダウンロードしてファイルシステムに保存しようとします。そのために Meteor.http パッケージを使用していますが、実際には、ファイルをダウンロードすると破損しているようです。

var fileUrl = 'http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=5'; //for example
Meteor.http.call("GET", fileUrl, function funcStoreFile(error, result) {
    "use strict";
    if (!error) {
        var fstream = Npm.require('fs'),
            filename = './.meteor/public/storage/' + collectionId;

        fstream.writeFile(filename, result.content, function funcStoreFileWriteFS(err) {
            if (!err) {
                var Fiber = Npm.require('fibers');
                Fiber(function funcStoreImageSaveDb() {
                    MyfileCollection.update({_id: collectionId}, {$set: {fileFsPath: filename}});
                }).run();
            } else {
                console.log('error during writing file', err);
            }
        });
    } else {
        console.log('dl file FAIL');
    }
});

public/storage から ../.meteor/public/storage へのシンボリックリンクを作成して、URL ( http://localhost:3000/storage/myfileId )から直接ダウンロードできるようにしました。

このシステムでダウンロードしたファイルと、ブラウザから直接ダウンロードした同じファイルを比較すると、それらは異なります。私の概念の何が問題になっていますか?

4

1 に答える 1

2

同様の問題があり、この議論に基づいて解決策を作成しました: https://github.com/meteor/meteor/issues/905

meteor が内部で使用しているリクエスト ライブラリを使用することで、バイナリ ダウンロードの問題を回避できます。また、小さなファイルをファイルシステムに保存するのではなく、mongodb でエンコードされた base64 を直接保存することをお勧めします。meteor.com やその他のクラウド サービスにデプロイする予定がある場合は、これが最も簡単なソリューションです。開発中にパブリック ディレクトリにファイルを保存するときに見つけたもう 1 つの不具合は、パブリック ディレクトリの変更ごとに meteor がファイルをリロードしていることです。これにより、ファイルのチャンクがダウンロードされるため、データが破損する可能性があります。ここで、上記の議論に基づいて使用しているコードをいくつか示します。

Future = Npm.require("fibers/future")
request = Npm.require 'request'    
Meteor.methods
      downloadImage: (url) ->
        if url
          fut = new Future()
          options =
              url: url
              encoding: null
          # Get raw image binaries
          request.get options, (error, result, body) ->
              if error then return console.error error
              base64prefix = "data:" + result.headers["content-type"] + ";base64,"
              image = base64prefix + body.toString("base64")
              fut.ret image
          # pause until binaries are fully loaded
          return fut.wait()
        else false

Meteor.call 'downloadImage', url, (err, res) ->
  if res
    Movies.update({_id: id}, {$set: {image: res}})

これが役に立てば幸いです。

于 2013-05-24T14:42:03.463 に答える