我从我的黑莓应用程序调用.NET Web服务。在与ksoap2毫无关系但遇到麻烦之后,我决定手动完成所有工作。下面是一段代码:
byte [] postDataBytes = soapRequestEnvelope.getBytes();
byte [] dataRetrieved;
try
{
HttpConnection connection = (HttpConnection)Connector.open(URL);
connection.setRequestMethod(HttpConnection.POST);
connection.setRequestProperty("soapaction", soapAction);
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
os = connection.openOutputStream();
os.write(postDataBytes);
int rc = connection.getResponseCode();
if(rc == HttpConnection.HTTP_OK)
{
inputStream = connection.openInputStream();
dataRetrieved = new byte[(int)connection.getLength()];
int bytesRead = inputStream .read(dataRetrieved);
}
else
{
dataRetrieved = null;
}
String dataString = new String(dataRetrieved);
//HttpConnection = javax.microedition.io.HttpConnection
//inputStream = java.io.InputStream
我遇到的问题是,我从web服务调用中得到的xml被缩短了。
当我将接收到的字节数打印到屏幕上时,它有时会显示1170(这实际上是我在这种特殊情况下期望的响应大小)。
但其他时候接收的字节是702……为什么是702???
我已经连续测试了十几次,结果如下:
1170, 702, 1170, 1170, 702, 1170, 1170, 702, 1170, 702, 1170, 702, 702, 702, 1170, 702
但为什么是702??当它搞砸了又不起作用的时候,为什么它会这么始终如一??它总是分配1170字节,但为什么它有时只读取702字节?是吗?
这很奇怪。
编辑:我尝试将inputstream.available()打印到屏幕上进行比较,完全不一致。它在0,702和1170之间变化。有时可用字节是0或702,读取的字节是1170。我完全糊涂了。
任何帮助都将不胜感激。
谢谢你
最佳答案
在我含糊不清的评论之后,我想我应该具体说明我所说的“把那个read
放在一个循环中”是什么意思。作为defined,read将返回读取的字节数,如果到达文件结尾,则返回-1
。
从套接字读取数据时,可能是在从服务器返回所有数据之前调用read()
。这样做的实际效果是,您调用read()
得到的数据比预期的要少。这只是意味着您需要再次调用它(一次又一次),直到获得所有数据。
我建议您使用一个简单的固定大小的缓冲区并在read()
之间循环,直到您得到-1
为止,并对每个块执行一些操作(例如,将其写入文件中)。这可以防止您需要将整个文件放在内存中。例如:
byte buf[1024];
int len;
while((len = read(buf)) >= 0)
{
/* do something with len bytes of buf */
}
当然,你可以保证文件会很小,而且你真的希望整个文件都在内存中。在这种情况下,您可以(如上所述)只分配大小为
connection.getLength()
的缓冲区,但是您需要调用3-argread(byte[], int, int)
并执行更多的内务处理:int remain = (int) connection.getLength();
byte buf[remain];
int offset = 0, len;
while((len = read(buf, offset, remain)) >= 0)
{
offset += len;
remain -= len;
}