13

我目前正在开发一个应用程序,用于通过简单的 http post 将大型视频文件从 iPhone 上传到 web 服务。截至目前,我构建了一个 NSURLRequest 并在加载请求之前预加载了所有视频文件数据。如果文件很大,这自然会消耗大量内存,在某些情况下甚至是不可能的。

所以基本上我的问题是:是否有正确的方法来流式传输数据或以块的形式加载数据而不对网络服务器进行任何修改?

谢谢。

编辑澄清:我正在寻找一种将大型多部分/表单数据iPhone流式传输网络服务器的方法。不是反过来。

接受答案后编辑:我刚刚发现苹果有一些漂亮的源代码是为了这个确切的目的而编写的,它显示在帖子中附加了额外的数据,而不仅仅是大文件本身。万一有人需要它:SimpleURLConnections - PostController.m

另一个编辑:在使用来自苹果的那段源代码时,我遇到了一个非常愚蠢和丑陋的问题,即使是wireshark 也无法帮助我调试。当在引号之间声明边界字符串时(如苹果示例),一些网络服务器不理解边界字符串。我在 Apache Tomcat 上遇到了问题,删除引号效果很好。

4

3 回答 3

15

您可以NSInputStream使用NSMutableURLRequest. 例如:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:uploadURL];
NSInputStream *stream = [[NSInputStream alloc] initWithFileAtPath:filePath];
[request setHTTPBodyStream:stream];
[request setHTTPMethod:@"POST"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    NSLog(@"Finished with status code: %i", [(NSHTTPURLResponse *)response statusCode]);
}];
于 2012-09-27T17:41:39.967 回答
3

您可以使用 aNSInputStream提供要通过 发布的数据-[NSMutableURLRequest setHTTPBodyStream:]。这可能是从文件中读取的输入流。您可能需要connection:needNewBodyStream:在 URL 连接委托中实现该方法,以提供一个新的、未打开的流,以防系统需要重新传输数据。

于 2012-09-27T17:42:12.213 回答
2

做到这一点的一种方法是将异步 NSInputStream 与文件一起使用。当异步连接要求您提供更多数据时,您从文件中读取数据。你有几种方法可以做到这一点:

  • UNIX/BSD 接口。使用 open(或 fopen)、malloc、读取并从 malloced 数据创建一个 NSData 对象

  • 如果您知道,请使用上面的 mmap()

  • 使用 Foundation 类 NSFileHandle API 使用 ObjectiveC 或多或少地做同样的事情

You can read up on streams in the 'Stream Programming Guide'. If this doesn't work for you there are lots of open source projects that can upload files, for instance MKNetworkKit

于 2012-09-27T18:17:08.313 回答