Leitura de grande parte dos dados xml do soquete e análise em tempo real
Estou trabalhando em um cliente android que lê o fluxo contínuo de dados xml do meu servidor java por um soquete TCP. O servidor envia um caractere '\ n' como delimitador entre respostas consecutivas. Abaixo está uma implementação de modelo ..
<response1>
<datas>
<data>
.....
.....
</data>
<data>
.....
.....
</data>
........
........
</datas>
</response1>\n <--- \n acts as delimiter ---/>
<response2>
<datas>
<data>
.....
.....
</data>
<data>
.....
.....
</data>
........
........
</datas>
</response2>\n
Bem, espero que a estrutura esteja clara agora. Essa resposta é transmitida do servidor zlib compactado. Portanto, primeiro tenho que inflar o que estiver lendo do servidor, separar na resposta usando delimitador e analisar. EEstou usando o SAX para analisar meu XML
Agora, meu principal problema é que a resposta xml vinda do servidor pode ser muito grande (pode estar no intervalo de 3 a 4 MB). Entã
para separar respostas com base no delimitador (\ n), tenho que usar um stringBuilder para armazenar blocos de resposta enquanto lê do soquete e em alguns telefones, o StringBuilder não pode armazenar cadeias no intervalo MegaBytes. Está dandoFora da memóri exceção e de threads comoist Conheci que manter cordas grandes (mesmo que temporariamente) não é uma boa idei
Próximo Tentei passar o inflatorReadStream (que, por sua vez, extrai dados do fluxo de entrada do soquete) como o fluxo de entrada do analisador SAX (sem me preocupar em separar o xml sozinho e com a capacidade do SAX de encontrar o final do documento com base em tags). Desta vez, uma resposta é analisada com êxito, mas, ao encontrar o delimitador '\ n', o SAX lança ExpatParserParseException dizendojunk após o elemento do documento .
Depois de pegar isso ExpatParserParseException Tentei ler novamente, mas depois de lançar a exceção, o SAX Parser fecha o fluxo; portanto, quando tento ler / analisar novamente, ele está dando IOException dizendo que o fluxo de entrada está fechadUm trecho de código do que eu fiz é fornecido abaixo (todos os blocos de captura de tentativa não relacionados foram removidos para maior clareza
private Socket clientSocket = null;
DataInputStream readStream = null;
DataOutputStream writeStream = null;
private StringBuilder incompleteResponse = null;
private AppContext context = null;
public boolean connectToHost(String ipAddress, int port,AppContext myContext){
context = myContext;
website = site;
InetAddress serverAddr = null;
serverAddr = InetAddress.getByName(website.mIpAddress);
clientSocket = new Socket(serverAddr, port);
//If connected create a read and write Stream objects..
readStream = new DataInputStream(new InflaterInputStream(clientSocket.getInputStream()));
writeStream = new DataOutputStream(clientSocket.getOutputStream());
Thread readThread = new Thread(){
@Override
public void run(){
ReadFromSocket();
}
};
readThread.start();
return true;
}
public void ReadFromSocket(){
while(true){
InputSource xmlInputSource = new InputSource(readStream);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = null;
XMLReader xr = null;
try{
sp = spf.newSAXParser();
xr = sp.getXMLReader();
ParseHandler xmlHandler = new ParseHandler(context.getSiteListArray().indexOf(website), context);
xr.setContentHandler(xmlHandler);
xr.parse(xmlInputSource);
// postSuccessfullParsingNotification();
}catch(SAXException e){
e.printStackTrace();
postSuccessfullParsingNotification();
}catch(ParserConfigurationException e){
e.printStackTrace();
postSocketDisconnectionBroadcast();
break;
}catch (IOException e){
postSocketDisconnectionBroadcast();
e.printStackTrace();
e.toString();
break;
}catch (Exception e){
postSocketDisconnectionBroadcast();
e.printStackTrace();
break;
}
}
}
E agora minhas perguntas são
xiste alguma maneira de fazer o SAX Parser ignorar caracteres indesejados após a resposta xml, e não lançar exceção e fechar o fluxSe não, existe alguma maneira de evitar erros de falta de memória no stringBuilder. Para ser franco, não estou excluindo uma resposta positiva sobre isso. Alguma solução alternativa?