David Kasabji
David Kasabji

Reputation: 1069

What is wrong with InputStream?

APP IDEA: I am struggling with fetching a XML file from Web and storing it on Internal Storage. My App checks whether there is a Internet Connection, when the user clicks button "Search" in MainActivity.

  1. If there is the an Internet connection, then I should fetch the XML from the given URL and store it in a file on Internal Storage.

  2. If there is no internet connection, I should just work with the stored file.

WHAT IS WRONG: The problem that occurs is, that if I have WiFi enabled, it wont get the InputStream to be parsed through web - so there will be no output (when a user clicks Search it wont find that word in XML, although it exists). However, if the WiFi is OFF, then it will find the very same word in the stored file. (please check sample code below for more clarification).

MY CODE (this is in HandleXML.java):

 public void handlingOnlineXML(Context ctx) throws XmlPullParserException, IOException {
        InputStream is;

        /*
         * Fetching the XML file from the Web
         */
        URL url = new URL("http://meteo.arso.gov.si/uploads/probase/www/observ/surface/text/sl/observation_si_latest.xml");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        Log.d(TAG,"The response is: " + response);
        is = conn.getInputStream();

        /*
         * Initiating XMLPullParser and sending the InputStream
         * into parseXMLandStoreIt method
         */
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser xpp = factory.newPullParser();



        /*
         * Saving Input Stream to a Internal Storage file
         */
        InputStream ins = is;
        try {
            final File file = new File(ctx.getFilesDir(), "data.xml");
            final OutputStream output = new FileOutputStream(file);

            try {
                final byte[] buffer = new byte[1024];
                int read;

                while ((read = ins.read(buffer)) != -1)
                    output.write(buffer, 0, read);

                output.flush();
            } finally {
                output.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
                , false);
        xpp.setInput(is, null);
        parseXMLAndStoreIt(xpp);
        is.close();
        ins.close();

    }

    /*******************************************************************
     * Here I handle the XML data from a file stored on local storage
     ******************************************************************/

    public void handlingStoredXML(Context ctx)throws XmlPullParserException, IOException{
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser xpp = factory.newPullParser();

        xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
                , false);

        //File file = new File(ctx.getFilesDir(), "data.xml")
        File file = new File(ctx.getFilesDir()+"/data.xml");
        if(file.exists()) {
            Log.d(TAG, "File Found!");
        }
        else{
            Log.d(TAG, "There's no file!");
        }

        InputStream is = ctx.openFileInput("data.xml");

        try {

            xpp.setInput(is, null);
            parseXMLAndStoreIt(xpp);
        }finally {
            is.close();
        }
    }

MY CONCLUSION: By observating behaviour in logcat and with some line switching, I think I noticed that the arranging of code matters. If I put

xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
            , false);
    xpp.setInput(is, null);

before the Saving File process, the WiFi ON option will work, and the WiFi OFF option won't work. However, if put the above mentioned after the saving file process (like in the sample code here), then WiFi ON option won't work, and WiFI OFF option will work.

This is really strange and I don't know what is causing this. What I think the problem is, that the InputStream gets deleted after it's first use ?

For example:

If I use InputStream for Saving a File, it will get deleted so there will be nothing to put into xpp.setInput(is,null); parseXMLAndStoreIt(xpp);

or the other way around, if I use InputStream for parsing Online, it will get emptied and nothing will be saved ?

LOGCAT(when WiFi off works, but ON doesn't): RATECE is word that I type when clicking Search

11-26 10:25:10.791  29471-29471/com.example.myweatherapp.myweatherapp D/Input Location:﹕ RATECE
11-26 10:25:10.791  29471-29471/com.example.myweatherapp.myweatherapp D/Input Location:﹕ RATECE
11-26 10:25:10.821  29471-29487/com.example.myweatherapp.myweatherapp D/TAG﹕ The response is: 200

I also use IF statement to check whether the File exists - and I can confirm that the App finds the above mentioned file.

LOGCAT (when the WiFi off doesn't work,and ON works):

11-26 10:43:44.021  30709-30709/com.example.myweatherapp.myweatherapp D/Input Location:﹕ RATECE
11-26 10:43:44.021  30709-30709/com.example.myweatherapp.myweatherapp D/TAG﹕ File Found!
11-26 10:43:44.021  30709-30709/com.example.myweatherapp.myweatherapp D/TAG﹕ File Found!

Please help me.

Upvotes: 1

Views: 112

Answers (1)

greenapps
greenapps

Reputation: 11224

You are reading InputStream is twice. That is not possible. With the first reading you have already 'consumed' it. The parser will get an error like 'stream already consumed' if it tries to read the stream for the second time. You have to adapt your design. Just use always the file to parse for example. Or use a StringBuider to read the response in a String and then parse the string. You can then also save the string.

Upvotes: 2

Related Questions