如何从文件系统发送包含 json 字符串和大文件的多部分数据的 HTTP 请求?

Posted

技术标签:

【中文标题】如何从文件系统发送包含 json 字符串和大文件的多部分数据的 HTTP 请求?【英文标题】:How to send an HTTP request with multipart data containing a json string and a big file from the file system? 【发布时间】:2015-11-20 12:14:50 【问题描述】:

上下文

我想发送一个包含由两段组成的多部分正文数据的 HTTP 请求:

    包含一些元数据的 JSON 字符串 一些文件二进制数据

我已经知道的

正如answer 中所述,这可以很容易地完成。但是在文件可​​能很大的情况下会发生什么?有了这个新的约束,我们自然不能将数据封装在 NSData 对象中,因为这会占用大量的内存资源。

熟悉NSURLRequest 类的人的第一个想法是使用HTTPBodyStream 属性而不是HTTPBody。但是如何获得一个可以同时写入 JSON 和文件数据段(以及边界和其他必需的 HTTP 内容)的流呢?

出路是继承NSInputStream。事实上,我注意到 AFNetworking 框架使用了这种方法。但据我所知,NSStream 类中有很多未记录/奇怪的方法可以覆盖,如here 所述,在我看来,这听起来需要做很多(潜在危险的)工作实现一些看似简单的事情。


问题

有没有办法实现所需的行为?请考虑以下限制:

没有第三方框架 使用干净的方法(不要覆盖未记录的方法,因为它们可能会在未来的 SDK 上发生变化)

【问题讨论】:

【参考方案1】:

你可以使用我的开源POSInputStreamLibrary。它提供了流式传输您想要的任何数据的能力。您唯一需要做的就是实现POSBlobInputStreamDataSource 协议并将实现用作POSBlobInputStream 的参数。

如果您强烈限制使用 3rd 方框架,您可以使用 POSBlobInputStream 作为示例,它实现了私有 API 方法以使自定义 NSInputStream 可行。

请随时询问有关实施细节的任何问题,祝您好运。

【讨论】:

感谢您的回答。这看起来是一种有趣的方法,我想它会解决我的问题。但是我查看了您的 POSBlobInputStream 类实现,发现您还没有实现 '_scheduleInCFRunLoop:forMode:'、'_setCFClientFlags:callback:context:' 和 '_unscheduleFromCFRunLoop:forMode:' 方法。这些是我在问题中提到的“危险的无证”方法。根据我在此链接中阅读的内容:blog.bjhomer.com/2011/04/subclassing-nsinputstream.html 它们可能导致应用崩溃 当然,我还没有实现任何东西。根据您的经验,您是否认为 NSInputStream 子类应该在不实现这些方法的情况下正常工作? 感谢@GabrielHuff 的提问。神奇之处在于方法resolveInstanceMethod:。它在传入的未知选择器中删除“_”前缀,并尝试将调用重定向到没有它的方法。 POSBlobInputStream.m_scheduleInCFRunLoop:forMode:_setCFClientFlags:callback:context:_unscheduleFromCFRunLoop:forMode: 不带下划线的同伴可以查看POSBlobInputStream.m

以上是关于如何从文件系统发送包含 json 字符串和大文件的多部分数据的 HTTP 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JavaScript 将 JSON 文件从 HTML 页面发送到 ESP

JSON 编码和大引号

如何从目录中读取文件并作为 JSON 发送给客户端?

如何从 JSON 文件中向用户发送消息?

我如何通过 json 将数据从我的设备发送到我的 php 文件

如何将 JSON 数据从节点 js 脚本发送到不同服务器上的 HTML 文件