Я хотел бы добавить три «части» в NSInputStream: NSString, вывод из другого потока и еще один NSString. Идея заключается в следующем:
Первая и последняя строки NSString представляют собой начало и конец запроса SOAP, в то время как вывод потока является результатом загрузки очень большого файла и его кодирования в виде строки Base64. Итак, в конце концов, я бы хотел, чтобы последний NSInputStream содержал весь запрос SOAP следующим образом:
‹ мыльное начало > ‹ Данные в кодировке Base64 > ‹ мыльное окончание >
Причина, по которой я хочу, чтобы весь запрос хранился в NSInputStream, двояка:
- Я не знаю, что загружать очень большой файл данных в память
Я думаю, что это единственный способ принудительно отправить окончательный запрос в виде фрагментов HTTP 1.1 (что мне нужно, потому что иначе, если запрос станет слишком большим, сервер его не примет). Итак, я знаю, что делаю это:
NSInputStream *dataStream = ....; [request setHTTPBodyStream:dataStream];
гарантирует, что запрос будет отправлен как фрагменты HTTP 1.1, а не как один огромный необработанный запрос SOAP.
Итак, мне интересно, как этого можно добиться, а именно, как мне «ставить в очередь» вещи в NSInputStream? Можно ли это сделать? Есть ли альтернативный способ?
Просто для справки, в Java это можно сделать следующим образом
Vector<InputStream> streamVec = new Vector<InputStream>();
BufferedInputStream fStream = new BufferedInputStream(fileData.getInputStream());
Base64InputStream b64stream = new Base64InputStream(fStream, true);
String[] SOAPBody = GenerateSOAPBody(fileInfo).split("CUT_HERE");
streamVec.add(new ByteArrayInputStream(SOAPBody[0].getBytes()));
streamVec.add(b64stream);
streamVec.add(new ByteArrayInputStream(SOAPBody[1].getBytes()));
SequenceInputStream seqStream = new SequenceInputStream(streamVec.elements());
потому что в Java эти объекты доступны, но NSStreams в target-c выглядят как объекты очень низкого уровня, и с ними очень сложно работать.
Примечание. Я полностью переписал исходный вопрос, заданный 2 дня назад, так как я думаю, что новое редактирование более четко объясняет, в чем проблема. Я надеюсь, что это поможет легче понять и, возможно, ответить
ОБНОВЛЕНИЕ 2
Вот чего мне удалось добиться на данный момент: вместо того, чтобы пытаться поставить в очередь поток, я использую временный файл, чтобы сначала записать начало мыла ‹ >, затем я настраиваю входной поток для чтения из файла в чанки, кодирую каждый чанк как строку Base64 и записываю это в тот же временный файл, наконец, когда мой поток закрывается, я записываю мыльное окончание ‹ > во временный файл. Затем я настраиваю другой входной поток с содержимым этого файла, который я передаю в NSMutableURLRequest:
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
...
NSInputStream *dataStream = [NSInputStream inputStreamWithFileAtPath:_tempFilePath];
[request setHTTPBodyStream:dataStream];
Это обеспечивает поблочную передачу содержимого файла по HTTP 1.1. После завершения подключения удалите временный файл.
Кажется, это работает нормально, но, конечно, это раздражает. Я не хочу писать во временный файл, когда все это можно было бы обработать потоками (в идеале). Если у кого-то все еще есть лучшие предложения, дайте мне знать :)
ОБНОВЛЕНИЕ 3
Хорошо, еще одно обновление в порядке. Хотя моя запись в файл, кажется, работает, я столкнулся с неожиданной проблемой, когда некоторые из моих запросов не загружаются на сервер. В частности, все идет по плану, я читаю содержимое временного файла в поток и устанавливаю тело HTTP моего запроса в этот поток, и он начинает передавать фрагменты HTTP 1.1, как я хочу, но для некоторых причина, по которой некоторые пакеты отбрасываются, а окончательный запрос — это мое предположение — искажается и, таким образом, терпит неудачу. Я думаю, что проблема с отброшенными пакетами является случайной, потому что я наблюдаю ее на больших запросах, то есть проблема просто имеет больше шансов проявиться, в то время как мои небольшие запросы обычно проходят нормально. Это, конечно, отдельный вопрос от оригинала в этом вопросе. Если у кого-нибудь есть хорошее представление о том, что может быть причиной этого, я спросил о проблеме здесь: Пакеты отброшены во время сегментированного запроса HTTP 1.1, отправленного NSURLConnection