我在解析InputStream并获取其数据的加载百分比时遇到问题。我的意思是,我的方法需要解析InputStream,将它放入StringBuffer,获取解析的字节总数,并根据我的StringBuffer返回一个String。
private String processPercent(InputStream content, HttpResponse response) throws IOException
{
InputStream in = content;
int totalBytes = Integer.parseInt(response.getFirstHeader("Content-Length").getValue());
int processedByte;
int loaded = 0;
StringBuffer sb = new StringBuffer();
while((processedByte = in.read()) != -1)
{
sb.append((char) processedByte);
if(this.asyncTask instanceof IProgressPercent)
{
lastProcessed = processedByte;
loaded += processedByte;
float percent = ((100*loaded) / totalBytes);
this.progressPercent = (int)percent;
this.asyncTask.doProgress(this.progressPercent);
}
}
in.close();
return new String(sb);
}
问题是,当我显示百分比变量的值时,我得到一个高于100的值,所以我认为这是一个计算问题。
有什么想法吗?感谢。
答案 0 :(得分:2)
替换
loaded += processedByte;
与
++loaded;
实际上在if
之前;递增1。
答案 1 :(得分:2)
这里有几个问题。
首先,您使用的是InputStream
; InputStream
读取字节。而char
不是两个byte
。 char
是UTF-16代码单元。请参阅here。
其次,您只能逐字节读取。如果您的内容长度为1M,您将调用此代码1M次。这真的是你想要的吗?
您应该通过以下方式更改代码:
InputStreamReader
- 使用InputStream
并使用正确的字符集启动; read()
方法读取预分配的char数组;使用 chars 读取的数量来更新进度条; char[]
的内容添加到StringBuffer
(真的应该是StringBuilder
)。由于解码过程产生的char
s比实际字节少,所以这意味着你的计数器会稍微偏离;它可以使用更复杂的机制来治愈,但这需要相当多的代码。
当然,更简单的方法是,如果尺寸不是太大,请直接下载所有内容,将其放入ByteArrayOutputStream
,然后解码ByteArrayOutputStream
的内容为String
。
答案 2 :(得分:-1)
而不是
float percent = ((100*loaded) / totalBytes);
使用
float percent = 100 * (loaded / totalBytes);