将数据加入NSInputStream中?

11
我想在NSInputStream中添加三个“部分”:一个NSString,另一个流的输出以及另一个NSString。其思路如下:
第一个和最后一个NSString表示SOAP请求的开头和结尾,而来自流的输出是加载非常大的文件并将其编码为Base64字符串的结果。因此,最终我将拥有最终的NSInputStream,其中包含整个SOAP请求,如下所示: < soap beginning > < Base64 encoded data > < soap ending > 我希望整个请求都保存在NSInputStream中的原因有两个:
  1. I don't what to load the very large data file into memory
  2. I think that this is the only way to enforce sending the final request in HTTP 1.1 chunks (which I need because otherwise, if the request becomes too big, the server won't accept it). So, I know that doing this:

    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有这些对象可用,而Objective-C中的NSStreams看起来像是非常低级的对象,并且很难使用。
注:我完全重新编写了2天前的原始问题,因为我认为新的编辑更清楚地解释了问题。我希望它能更容易地被理解和回答。
更新2:
到目前为止,我已经实现了以下内容:不再尝试将东西排队到流中,而是使用一个临时文件首先写入< soap beginning >,然后设置一个输入流以块读取该文件,在对每个块进行Base64编码并将其写入同一临时文件之后,最后当流关闭时,将< soap ending >写入临时文件。然后我使用此文件的内容设置另一个输入流,将其传递给NSMutableURLRequest:
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
        ...
        NSInputStream *dataStream = [NSInputStream inputStreamWithFileAtPath:_tempFilePath];
        [request setHTTPBodyStream:dataStream];

这确保了文件内容通过HTTP 1.1分块传输。连接完成后,删除临时文件。
这似乎可以正常工作,但当然这是一个令人恼火的解决方法。如果所有操作都可以通过流来处理(理想情况下),我不想写入临时文件。如果有更好的建议,请告诉我 :)

更新3

好的,需要更新一下。虽然我写入文件的方法似乎行得通,但现在我遇到了一个意外的问题:我的一些请求上传到服务器时失败了。具体而言,一切都按计划进行,我正在将临时文件的内容读入流中,并将请求的HTTP正文设置为此流,并且开始传输HTTP 1.1块,就像我想要的那样 - 但是由于某种原因,一些数据包却被丢弃了,最终的请求(这只是我的猜测)失效了。我认为数据包丢失的问题是随机的,因为我在较大的请求上观察到它 - 也就是说,这个问题更容易出现 - 而我的较小请求通常都能成功通过。当然,这当然是与此问题的原始问题分开的另一个问题。如果有人对可能导致这种情况的好主意,请参考这里提出的问题:Packets dropped during chunked HTTP 1.1 request sent by NSURLConnection

1个回答

0

你的解决方案是一个可以接受的选项,但你也可以使用流来实现。这意味着需要子类化NSInputStream,而这并不容易,因为你需要实现一堆方法。

基本上,你的子类最初会返回头部字节,然后它会从“内部”流返回文件内容的字节,当用完时,它会返回尾部字节。这意味着需要记录头部和尾部的大小以及已处理的数量,但这不是一个大问题。

这里有一个创建子类的示例here,它展示了你需要实现的棘手的隐藏方法,以使流子类正常工作而不抛出异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接