Search code examples
androidxmlinputstreamfileinputstream

InputStream from file in internal memory opens incomplete (due to invalid char in file?)


Why the code below works when I parse a StringReader, but not an InputStream from a file located in the internal memory, even though the file has exactly the same data from the String used before (commented in code)? The parser reaches EOF right after the second line. When I use the String, it goes all the way to the end. The variable linha is just to see, during debugging, what line is being parsed and when I use the InputStream approach, the parser reaches EOF in line 2 of the file.

    public boolean read(){
    boolean ret = false;
    try{
        InputStream is =  mContext.openFileInput(fileName);



        if(is!=null) {

            XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
            XmlPullParser myparser = xmlFactoryObject.newPullParser();
            xmlFactoryObject.setNamespaceAware(true);
            myparser.setInput(is,null); //or myparser.setInput(is,"utf-8");
            int event;
            String name = null;
            boolean sai = false;
            event=myparser.getEventType();
            do{
                linha = myparser.getLineNumber();
               if ((event == XmlPullParser.START_TAG)
                   &&((name=myparser.getName()).equals("list-of-commands")))
                       sai = true;
               else
                    event = myparser.next();
            }while(!sai && event!= XmlPullParser.END_DOCUMENT);
            if((name!=null) && myparser.getAttributeValue(null,"machine").equals(modelName)){
                MachineCommand novoParam = null;
                int itemCount = 0;
                while (event != XmlPullParser.END_DOCUMENT) {
                    linha = myparser.getLineNumber();
                    name = myparser.getName();
                    switch (event) {
                        case XmlPullParser.START_TAG:
                            if (name.equals("param")) {
                                itemCount = 0;
                                int numComando =
                                        Integer.parseInt(myparser.getAttributeValue(null,"num_command"));
                                int numParam =
                                        Integer.parseInt(myparser.getAttributeValue(null,"num_param"));
                                novoParam =
                                        ((MachineCommand) progMenu.getExpandableListAdapter()
                                                .getChild(numComando, numParam))
                                                .deepClone(mContext);
                                novoParam.setNumCommand(numComando);
                                novoParam.setNumParam(numParam);
                            } else if (name.equals("spinner")) {
                                int selected =
                                   Integer.parseInt(myparser.getAttributeValue(null,"selected_pos"));
                                Spinner sp = (Spinner)novoParam.getValueAt(itemCount++);
                                sp.setSelection(selected);
                            } else if (name.equals("EditTextNoKB")) {
                                String text = myparser.nextText();
                                EditTextNoKB et = (EditTextNoKB)novoParam.getValueAt(itemCount++);
                                et.setText(text);
                            }
                            break;
                        case XmlPullParser.END_TAG:
                            if (name.equals("param")) {
                                ((ArrayAdapter<MachineCommand>)(dslvProgList.getAdapter())).add(novoParam);
                            }
                    }
                    event = myparser.next();
                }
                if(dslvProgList.getCount()>0) ret = true;
            }
        }
    }catch(Exception e) {
        e.printStackTrace();
        ret = false;
    }


    return ret;

}

The xml file to be parsed is below:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<list-of-commands machine="1005" version="1.0.0">
  <param num_command="0" num_param="0">Velocidade<EditTextNoKB>6</EditTextNoKB></param>
  <param num_command="0" num_param="2">Sentido<Spinner selected_pos="1">Anti-horário</Spinner></param>
  <param num_command="0" num_param="5">Zerar Contador</param>
  <param num_command="0" num_param="1">Desacelerar<EditTextNoKB>69</EditTextNoKB>voltas</param>
  <param num_command="2" num_param="4">Aguardar Liberar</param>
</list-of-commands>

EDIT: As pointed in the comments below, I could state the problem is in the write procedure of the file. Maybe some invalid char? Here is the code used to create the file in the internal memory:

    public boolean write(){
    try {
        FileOutputStream fos = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);


        XmlSerializer serializer = Xml.newSerializer();
        serializer.setOutput(fos, "utf-8");
        serializer.startDocument("utf-8", true);
        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

        serializer.startTag(null, "list-of-commands");
        serializer.attribute(null, "machine", modelName);  //TO DO: Estes dois atributos devem ser
        serializer.attribute(null,"version","1.0.0"); //definidos em arquivo de configuração

        for(int i=0; i<dslvProgList.getCount()-1; i++){
            MachineCommand com = (MachineCommand)dslvProgList.getItemAtPosition(i);
            serializer.startTag(null,"param");
            serializer.attribute(null, "num_command", com.getStringNumCommand());
            serializer.attribute(null,"num_param",com.getStringNumParam());
            serializer.text(com.getName());
            for (int j=0; j<com.getNumOfValues(); j++){
                View v = com.getValueViewAt(j);
                if(v instanceof EditTextNoKB){
                    serializer.startTag(null, "EditTextNoKB");
                    serializer.text(((EditTextNoKB)v).getText().toString());
                    serializer.endTag(null, "EditTextNoKB");
                }
                else if(v instanceof Spinner){
                    serializer.startTag(null, "Spinner");
                    int selectedPos = ((Spinner) v).getSelectedItemPosition();
                    serializer.attribute(null, "selected_pos", String.valueOf(selectedPos));
                    serializer.text(((Spinner) v).getItemAtPosition(selectedPos).toString());
                    serializer.endTag(null, "Spinner");
                }
            }
            serializer.text(com.getUnity());
            serializer.endTag(null, "param");
        }
        serializer.endTag(null, "list-of-commands");
        serializer.endDocument();

        serializer.flush();

        fos.close();
    }catch (Exception e){
        return false;
    }
    return true;
}

Solution

  • Turns out it was just something really stupid. The whole problem was my encoding string: "UTF-8". The right one would be "utf-8" (NO CAPITALS). It was wrong on writing and reading. I'll edit the code to reflect the right one. @OneWorld: Thank you and you are right, the issue is on writing and then reflects on reading. Do you think I should delete this question, or should I leave it here as answered, so other people can benefit of it? As it was a silly mistake, I'm not sure I should keep it. I'm new here, so I ask for your tip on this.