一次读取一行文本,并将所述行分别附加到一个字符串中,这在提取每一行时都非常耗时,并且s o许多方法调用。
我能够通过分配一个相当大的字节数组来保存流数据,并且在需要时迭代地用一个更大的数组替换,并尝试读取与数组一样多的数据,从而获得更好的性能。
由于某些原因,当代码使用由HTTPUrlConnection返回的InputStream时,Android多次无法下载整个文件,所以我不得不诉诸同时使用BufferedReader和手动超时机制来确保我得到整个文件或取消传输。
private static final int kBufferExpansionSize = 32 * 1024;
private static final int kBufferInitialSize = kBufferExpansionSize;
private static final int kMillisecondsFactor = 1000;
private static final int kNetworkActionPeriod = 12 * kMillisecondsFactor;
private String loadContentsOfReader(Reader aReader)
{
BufferedReader br = null;
char[] array = new char[kBufferInitialSize];
int bytesRead;
int totalLength = 0;
String resourceContent = "";
long stopTime;
long nowTime;
try
{
br = new BufferedReader(aReader);
nowTime = System.nanoTime();
stopTime = nowTime + ((long)kNetworkActionPeriod * kMillisecondsFactor * kMillisecondsFactor);
while(((bytesRead = br.read(array, totalLength, array.length - totalLength)) != -1)
&& (nowTime < stopTime))
{
totalLength += bytesRead;
if(totalLength == array.length)
array = Arrays.copyOf(array, array.length + kBufferExpansionSize);
nowTime = System.nanoTime();
}
if(bytesRead == -1)
resourceContent = new String(array, 0, totalLength);
}
catch(Exception e)
{
e.printStackTrace();
}
try
{
if(br != null)
br.close();
}
catch(IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
编辑:事实证明,如果你不需要有内容重新编码(即你想要的内容AS IS),你应该不使用任何读者的子类。只需使用适当的Stream子类。
将上述方法的开头替换为以下相应的行,以加快额外的2到3次。
String loadContentsFromStream(Stream aStream)
{
BufferedInputStream br = null;
byte[] array;
int bytesRead;
int totalLength = 0;
String resourceContent;
long stopTime;
long nowTime;
resourceContent = "";
try
{
br = new BufferedInputStream(aStream);
array = new byte[kBufferInitialSize];
正是!这也在Java有效项目51中进行了解释。我曾尝试使用分析并使用StringBuilder而不是String来节省大量处理时间。 – 2011-12-08 13:24:31
对于奖励积分,提供初始容量以避免在StringBuilder填充时重新分配: 'StringBuilder total = new StringBuilder(inputStream.available());' – dokkaebi 2012-01-22 07:04:02
这不会删除换行符吗? – schwiz 2012-05-10 04:35:50