2014-04-14 32 views
1

我在低内存嵌入式设备上运行ServiceStack(v3)。ServiceStack使用块/缓冲区上传大文件

外部客户端可以将大文件推送到此设备以在内部存储在硬盘上。

我按照this CodePlex文章中的步骤操作,但ServiceStack中的Post()方法只在文件上载完成时才被调用。这使我相信ServiceStack将整个文件缓存到内存中。

我需要自己处理System.IO.Stream的能力,并在每个块变为可用时处理每个块,以便我可以立即将数据写入磁盘。

我该怎么做?

回答

4

您没有声明您使用的是单声道,但我假设您将在嵌入式设备上运行。您遇到的问题是由HttpRequest.Mono.cs造成的。 multipart/form-data(这是大多数JavaScript文件上传库使用的内容)被该类自动拉入内存流中,并可通过Request.Files获得。通常这很好,并且使上传文件变得非常容易。问题出现在你想上传大量东西时。

如果你读了this StackOverflow的反应,你会被指示采取DTO的控制自己使用IRequiresRequestStream反序列化this CodeProject上的文章所以我刮起了ServiceStack服务和AngularJS客户对它进行测试。 Here is my first pass at the solution

不幸的是,它没有按预期工作。消息部分仍然被反序列化为Request.Files,如MemoryStream的。这是因为multipart/form-data仍然被拦截,并在HttpRequest.Mono的请求处理链中处理得很低。

进一步的研究表明,multipart/form-data协议对于小文件很有用,但as mythz himself points out这并不是真的意味着上传大量数据。有更好的方法去这样做的大文件上传...

我建议的解决这个问题是使用IRequiresRequestStreammultipart/form-data远离,只是直接上传二进制数据作为原始类型(Content-Type: image/jpeg,例如。 )您必须自己分块并重新组合文件,但是您将完全控制该过程,并且您将全部处理任何大小的上传。 Here is the final sample code

+0

从NuGet ServiceStack 4.0.54开始,这仍然是正确的 - 整个流似乎被复制到MemoryStream中,因此在Mono中这部分API的整体文件流方法被打破。我似乎成功使用IRequiresRequestStream并将方法更改为PUT,因为它似乎绕过了LoadMultipart(Mono 4.x)中存在的有问题的MemoryStream使用。因人而异。 –