Meteor 如何使用文件系统和CollectionFS将文件保存在文件夹中?(是的,真的。)

Meteor 如何使用文件系统和CollectionFS将文件保存在文件夹中?(是的,真的。),meteor,save,filesystems,collectionfs,Meteor,Save,Filesystems,Collectionfs,我想我错过了什么。我读过很多文章/例子,但我无法在我的系统上保存图像(我在本地工作) 我的目标是什么? 我正在尝试将用户提交的文件保存在文件夹(服务器端)中。听起来容易吗?也许吧 有什么问题吗? 简短回答:我不知道如何将文件保存在我的文件夹中。 你想要更多的信息吗 文件上传的故事 我已经读到,要使用path参数,比如new FS.Store.FileSystem(“thumb”,{path:/public/images/user/avatar}),我必须声明我的收藏服务器端。但是当我调用Avat

我想我错过了什么。我读过很多文章/例子,但我无法在我的系统上保存图像(我在本地工作)

我的目标是什么? 我正在尝试将用户提交的文件保存在文件夹(服务器端)中。听起来容易吗?也许吧

有什么问题吗? 简短回答:我不知道如何将文件保存在我的文件夹中。 你想要更多的信息吗

文件上传的故事 我已经读到,要使用path参数,比如
new FS.Store.FileSystem(“thumb”,{path:/public/images/user/avatar})
,我必须声明我的收藏服务器端。但是当我调用
Avatars.insert()
(Avatars是我收藏的名称)时,它似乎不存在。这是有意义的,因为此集合仅存在于服务器上

所以我试着在服务器端和客户端声明集合(我读了一些关于这方面的示例),这是可行的!该文件已正确添加到MongoDB,但我的文件夹仍然为空(我不确定,但我认为这是因为
Avatars.insert()
被称为客户端,因此使用的集合是客户端集合,不能采用
路径
参数)

但没问题!我创建了两个Meteor方法(一个客户端和一个服务器端),称为“updateAvatarFile”。有了这个“技巧”,我就能够调用Meteor.call(“updateAvatarFile”,field.files[0]),它同时调用服务器端和客户端方法。所以我可以在客户端做一些UI工作,在另一个客户端上传文件。但我无法将该文件作为参数传递

field.files[0]
包含客户端文件,但服务器端文件是空对象。我的问题是:如何上传文件

我不能在客户端执行此操作(因为我不能使用
path
参数),但我可以将文件传递到服务器。我确信我遗漏了什么,但我不知道遗漏了什么。

我是这样说的:

// /client/views/templates/settings.js
Template.settings.events({
   'submit #updateAvatar': function (e, template) {
        e.preventDefault();
        const field = document.getElementsByName('avatar')[0];
        Meteor.call('updateAvatarFile', field.files[0]);
    }
});

// /client/lib/clientMethods.js
Meteor.methods({
    'updateAvatarFile': function (file) {
        // blabla
    }
});

// /server/lib/serverMethods.js
Meteor.methods({
    'updateAvatarFile': function (file) {
        Avatars.insert(file, function (err, fileObj) {
            if (err) {
                console.log(err);
            } else {
                console.log(fileObj);
            }
        });
    }
});

// /server/collections/serverAvatarCollection.js
Avatars = new FS.Collection("avatars", {
    stores: [
        new FS.Store.FileSystem("original", { path: "/public/images/user/avatar" }),
        new FS.Store.FileSystem("thumb", { path: "/public/images/user/avatar" })
    ],
    filter: {
        maxSize: 1000000, //1Mo
        allow: { contentTypes: ['image/*'] }
    },
    onInvalid: function (message) {
        //throw new Meteor.Error(403, message);
    }
});

// /client/collections/clientAvatarCollection.js
// (this one is actually in a comment block)
Avatars = new FS.Collection("avatars", {
    stores: [
        new FS.Store.FileSystem("original"),
        new FS.Store.FileSystem("thumb")
    ],
    filter: {
        maxSize: 1000000, //1Mo
        allow: { contentTypes: ['image/*'] }
    },
    onInvalid: function (message) {
        alert(message);
    }
});
我还尝试使用客户端方法插入该文件,但得到了相同的结果(该文件已添加到MongoDB,但未保存到文件夹)

使用不同的
路径
值也不起作用


编辑:或者我试图使用错误的软件包?在我看来,将图片转换成块并保存到MongoDB听起来真的很奇怪和糟糕。你有什么建议吗?


编辑2: 回答Michel Floyd(很抱歉,字符限制很烦人)

首先,谢谢你的回答

1。目前,我只是在尝试Meteor,所以我安装了
autopublish
unsecure
。不发布/订阅我的收藏不会导致问题,对吗

2.在您回答之前,我试图通过将我的
avatarCollection.js
放在
/collections
中,为服务器和客户端设置一个可用的集合。我在想,不包含服务器客户端的路径会自动为双方提供。那么
/collections
/lib
之间有什么区别呢?(我知道“lib”文件夹中的所有文件都是先加载的)。将集合放入
/collections
中是一种不好的做法吗?也许我应该创建一个
/lib/collections
文件夹


3.(最后一点,很抱歉这么长时间的评论)我已经尝试了你上面的建议,但似乎不起作用(或者我做错了什么,再次>您通常走的是正确的道路。CollectionFS使用存储适配器来处理实际的文件存储。您可以尝试将文件放在S3、gridFS或本地文件系统上。通常避免将文件内容直接放在Mongo中

首先,定义您的收藏:

Avatars = new FS.Collection("avatars", {
    stores: [
        new FS.Store.FileSystem("original", { path: "/public/images/user/avatar" }),
        new FS.Store.FileSystem("thumb", { path: "/public/images/user/avatar" })
    ],
    filter: {
        maxSize: 1000000, //1Mo
        allow: { contentTypes: ['image/*'] }
    },
    onInvalid: function (message) {
        //throw new Meteor.Error(403, message);
    }
});
/lib
!这将使它对服务器和客户端都可用

第二,确保你从服务器发布你的头像集合,并从客户端订阅。我在你的问题中没有看到任何发布/订阅代码。你需要它

第三,如果你只是这样做:

Avatars.insert(...);

在有文件的客户端上,然后CollectionFS然后CollectionFS将负责为您存储该文件。问题是,它不会立即可用。实际上载和存储可能需要一段时间。例如,您可以查看
fileObj.isupload
,查看该文件是否已准备就绪。

非常感谢您的回答。我已经编辑我的原始帖子以回复。1.如果您启用了autopublish,则发布不是您的问题。2.Meteor将非特殊目录中的文件发送到客户端和服务器的说法是正确的。3.
tempstore
目录仅在文件块进入存储适配器时临时使用。抱歉,延迟了。问题是文件块不会进入存储适配器(文件系统)。我的文件夹是空的,在向我的集合中插入某些内容后发生事件。您可以尝试直接向github项目上的CollectionFS人员询问文件系统适配器。我已将其用于S3和本地文件系统,并且它始终有效。