Подтвердить что ты не робот

Каков правильный способ отправки большого файла через HTTP POST, без загрузки всего файла в ram?

В настоящее время я работаю над приложением для загрузки больших видеофайлов с iPhone на веб-сервис через простую HTTP-почту. На данный момент я создаю NSURLRequest и предварительно загружаю все данные видеофайлов перед загрузкой запроса. Это, естественно, съедает тонну барана, если файл значительно большой, в некоторых случаях это даже не возможно.

Итак, в основном, мой вопрос: есть ли правильный способ потоковой передачи данных или загрузки его в куски без каких-либо изменений на веб-сервере?

Спасибо.

РЕДАКТИРОВАТЬ для пояснения:. Я ищу способ передачи больших данных multipart/form FROM веб-сервера iPhone TO. Не наоборот.

РЕДАКТИРОВАТЬ после принятия ответа: Я только выяснил, что у яблока есть отличный исходный код, написанный для этой конкретной цели, и он показывает добавление дополнительных данных к сообщению не только самому большому файлу. Если кому-то это понадобится: SimpleURLConnections - PostController.m

Еще один EDIT: При использовании этого фрагмента исходного кода из Apple я столкнулся с очень тупой и уродливой проблемой, которая даже wirehark не могла" t помогите мне отлаживать. Некоторые веб-серверы не понимают пограничную строку, когда она объявляется между кавычками (например, в примере яблок). У меня были проблемы с ним на Apache Tomcat, и удаление котировок работало просто замечательно.

4b9b3361

Ответ 1

Вы можете использовать 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]);
}];

Ответ 2

Вы можете использовать NSInputStream, чтобы предоставить данные для отправки через -[NSMutableURLRequest setHTTPBodyStream:]. Это может быть поток ввода, который читается из файла. Возможно, вам понадобится реализовать метод connection:needNewBodyStream: в вашем делете соединения с URL, чтобы предоставить новый, нераскрытый поток, если система должна повторно передать данные.

Ответ 3

Один из способов сделать это - использовать асинхронный NSInputStream совместно с файлом. Когда асинхронное соединение просит вас предоставить больше данных, вы читаете данные из файла. У вас есть несколько способов сделать это:

  • Интерфейс UNIX/BSD. использовать open (или fopen), malloc, читать и создавать объект NSData из malloced data​​p >

  • используйте приведенное выше с помощью mmap(), если вы знаете его

  • используйте API-интерфейс NSFileHandle класса Foundation, чтобы сделать более или менее то же самое с помощью ObjectiveC

Вы можете читать потоки в "Руководстве по программированию потоков". Если это не работает для вас, есть много проектов с открытым исходным кодом, которые могут загружать файлы, например MKNetworkKit