Leggere una riga di testo alla volta e aggiungere singolarmente detta riga a una stringa richiede molto tempo sia nell'estrazione di ciascuna riga sia nell'overhead di così tante invocazioni di metodi.
Sono stato in grado di ottenere prestazioni migliori allocando un array di byte di dimensioni decenti per contenere i dati di flusso e che viene sostituito iterativamente con un array più grande quando necessario e provando a leggere quanto l'array potrebbe contenere.
Per qualche motivo, Android non è riuscito a scaricare ripetutamente l'intero file quando il codice utilizzava InputStream restituito da HTTPUrlConnection, quindi ho dovuto ricorrere all'uso di un BufferedReader e di un meccanismo di timeout a rotazione manuale per assicurarmi che avrei ottenuto l'intero file o annullato il trasferimento.
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();
}
}
EDIT: Si scopre che se non è necessario ricodificare il contenuto (ovvero, si desidera il contenuto COSÌ COM'È ) non è necessario utilizzare nessuna delle sottoclassi di Reader. Basta usare la sottoclasse Stream appropriata.
Sostituisci l'inizio del metodo precedente con le righe corrispondenti di seguito per velocizzarlo da 2 a 3 volte in più .
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];