InputStream有什么问题?

时间:2014-11-26 09:24:17

标签: java android xml

APP IDEA:我正在努力从Web获取XML文件并将其存储在内部存储上。当用户点击MainActivity中的“搜索”按钮时,我的应用程序会检查是否存在Internet连接。

  1. 如果存在Internet连接,那么我应该从给定的URL获取XML并将其存储在Internal Storage上的文件中。

  2. 如果没有互联网连接,我应该使用存储的文件。

  3. 什么错误:出现的问题是,如果我启用了WiFi,它就不会通过网络解析InputStream - 因此没有输出(当用户点击搜索时它不会在XML中找到这个词,尽管它存在)。但是,如果WiFi为OFF,则它将在存储的文件中找到相同的单词。 (请查看下面的示例代码以获得更多说明)。

    我的代码(这是在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();
            }
        }
    

    我的结论:通过观察logcat中的行为并进行一些行切换,我想我注意到代码的排列很重要。如果我把

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

    在保存文件处理之前, WiFi ON选项将起作用,并且WiFi OFF选项将不起作用。但是,如果在保存文件过程之后输入上述内容(如此处的示例代码中所示),那么 WiFi ON选项将无法正常工作,并且WiFI OFF选项将起作用。

    这真的很奇怪,我不知道造成这种情况的原因。我认为问题是,InputStream在首次使用后会被删除吗?

    例如:

    如果我使用InputStream保存文件,它将被删除,因此无法放入xpp.setInput(is,null); parseXMLAndStoreIt(xpp);

    或者相反,如果我使用InputStream解析在线,它将被清空并且不会保存任何内容?

    LOGCAT(当WiFi关闭时,但不开启): RATECE是我点击搜索

    时输入的字词
    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
    

    我还使用IF语句检查文件是否存在 - 我可以确认应用程序找到上述文件。

    LOGCAT(当WiFi关闭不起作用且开启时):

    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!
    

    请帮帮我。

1 个答案:

答案 0 :(得分:2)

您正在阅读两次InputStream is。这是不可能的。在第一次阅读时,您已经“消耗”了它。如果解析器尝试第二次读取流,则会收到类似'stream already consume'的错误。你必须调整你的设计。例如,只需使用文件解析即可。或者使用StringBuider读取String中的响应,然后解析字符串。然后,您还可以保存字符串。