【问题标题】:Parse XML on Android using inputstream from Cache使用来自缓存的输入流在 Android 上解析 XML
【发布时间】:2012-03-30 15:36:40
【问题描述】:

我想从互联网上的服务器解析一个 XML 文件并在本地保存一段时间,这样如果连接丢失我仍然可以在应用程序上看到信息。

我能够成功解析来自 Internet 的 XML 文件。我还可以将它保存在缓存目录getCacheDir()、文件目录getFilesDir() 和外部存储中。

现在,我想解析本地 XML 文件,并且仍然想使用与从 Internet 解析 XML 相同的函数。但是,经过几次尝试和数小时的搜索,我无法从缓存目录或文件目录中存储的文件中解析inputstream。该函数作用的唯一目录是外部目录。

所以这段代码有效

inputstream is;
File file = new File ("/mnt/sdcard/Fmobile/Cache","Newfile.xml");                   
is = new BufferedInputStream(new FileInputStream(file));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document dom = db.parse(is); 

虽然以下代码工作。

inputstream is;
File file = new File (getFilesDir(),"Newfile.xml");                 
is = new BufferedInputStream(new FileInputStream(file));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document dom = db.parse(is); **// Error is given on this line : "Is a directory"**

谁能告诉我上面两个代码有什么区别,或者应该怎么做才能从缓存目录或文件目录中获取输入流。 只是为了让您知道我已尝试将 getFilesDir() 替换为文件的路径。

我搜索过的大多数解决方案都是关于将文件存储在资产或 res 文件夹中,但我不能这样做,因为它是一个会不断变化的动态文件,这就是我需要使用缓存和超时的原因。

对于我在发布此内容时可能犯的任何错误,我深表歉意。这是我的第一篇文章。

原木猫如下:

04-04 11:27:24.579: I/com.example.app1.FMobileActivity(16029): Running Form [2] Local File
04-04 11:27:24.579: I/com.example.app1.FMobileActivity(16029): ProcessForm Data2
04-04 11:27:24.579: I/com.example.app1.FMobileActivity(16029): /data/data/com.example.app1/cache/Newfile2.xml
04-04 11:27:24.589: E/com.example.app1.FMobileActivity(16029): Error occurred in ProcessForm:Is a directory
04-04 11:27:24.589: W/System.err(16029): java.io.IOException: Is a directory
04-04 11:27:24.599: W/System.err(16029):    at org.apache.harmony.luni.platform.OSFileSystem.read(Native Method)
04-04 11:27:24.599: W/System.err(16029):    at dalvik.system.BlockGuard$WrappedFileSystem.read(BlockGuard.java:165)
04-04 11:27:24.599: W/System.err(16029):    at java.io.FileInputStream.read(FileInputStream.java:290)
04-04 11:27:24.599: W/System.err(16029):    at java.io.FileInputStream.read(FileInputStream.java:245)
04-04 11:27:24.609: W/System.err(16029):    at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:140)
04-04 11:27:24.609: W/System.err(16029):    at java.io.BufferedInputStream.read(BufferedInputStream.java:225)
04-04 11:27:24.609: W/System.err(16029):    at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1044)
04-04 11:27:24.609: W/System.err(16029):    at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:114)
04-04 11:27:24.609: W/System.err(16029):    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
04-04 11:27:24.609: W/System.err(16029):    at com.example.app1.FMobileActivity.GetFormData(FMobileActivity.java:315)
04-04 11:27:24.609: W/System.err(16029):    at com.example.app1.FMobileActivity.onCreate(FMobileActivity.java:58)
04-04 11:27:24.609: W/System.err(16029):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-04 11:27:24.609: W/System.err(16029):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1666)
04-04 11:27:24.609: W/System.err(16029):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1727)
04-04 11:27:24.609: W/System.err(16029):    at android.app.ActivityThread.access$1500(ActivityThread.java:124)
04-04 11:27:24.609: W/System.err(16029):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:974)
04-04 11:27:24.609: W/System.err(16029):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-04 11:27:24.609: W/System.err(16029):    at android.os.Looper.loop(Looper.java:130)
04-04 11:27:24.609: W/System.err(16029):    at android.app.ActivityThread.main(ActivityThread.java:3859)
04-04 11:27:24.609: W/System.err(16029):    at java.lang.reflect.Method.invokeNative(Native Method)
04-04 11:27:24.609: W/System.err(16029):    at java.lang.reflect.Method.invoke(Method.java:507)
04-04 11:27:24.609: W/System.err(16029):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
04-04 11:27:24.609: W/System.err(16029):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:647)
04-04 11:27:24.609: W/System.err(16029):    at dalvik.system.NativeStart.main(Native Method)
04-04 11:27:24.609: E/com.example.app1.FMobileActivity(16029): Couldn't parse the Form.
04-04 11:27:24.689: D/dalvikvm(16029): GC_EXTERNAL_ALLOC freed 118K, 48% free 2837K/5379K, external 2743K/2773K, paused 33ms

【问题讨论】:

  • 您是否确定错误出现在该行而不是FileInputStream 构造函数上?请发布完整的堆栈跟踪。

标签: java android xml parsing inputstream


【解决方案1】:

当您下载 xml 文件时,请使用以下代码:

try {
            URL   urlxml = new URL(YOUR_XML_FILE_URL);
            URLConnection ucon = urlxml.openConnection();
            ucon.setConnectTimeout(4000);
            ucon.setReadTimeout(4000);
            InputStream is = ucon.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is, 128);
            FileOutputStream fOut =this.openFileOutput("myFile.xml", Context.MODE_WORLD_READABLE);
            OutputStreamWriter osw = new OutputStreamWriter(fOut);
            int length = ucon.getContentLength();
            int current = 0;
            long total = 0;
            while ((current = bis.read()) != -1) {
                total += current;
                osw.write((byte) current);
            }
            osw.flush();
            osw.close();

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            finishUpdate = false;
            e.printStackTrace();
        } catch (IOException e) {
            // TODO: handle exception
            finishUpdate = false;
        }

为了检索和解析下载的 xml 文件,请使用:

 SAXParserFactory fabrique = SAXParserFactory.newInstance();
    SAXParser parseur = null;
    ArrayList temp = null;
    try {
        parseur = fabrique.newSAXParser();
        DefaultHandler handler = new ParserXMLHandler();

        File fs=context.getFilesDir();
        File file = new File(fs.getAbsoluteFile(),"Myfile.xml");
        parseur.parse(file, handler);


    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    }

【讨论】:

  • 感谢您的回答。如果我没有对两个文件使用相同功能的限制(一个在互联网上,一个在本地存储),这将起作用。我也不能使用 SAXParser。我正在使用 javax.xml.parsers。但是你的回答让我对我遇到的另一个问题有了一个想法。谢谢
【解决方案2】:

db.parse 正在获取“文件”并返回“文档”。

也许您需要将代码更改为:db.parse(is) 为 db.parse(file)

【讨论】:

  • 不,它不起作用。它仍然给出相同的错误:"Is a directory". 在这个问题中让我感到困惑的是,如果我尝试从/mnt/sdcard/Fmobile/Cache 读取而不是从getFilesDir() 给出的/data/data/com.example.app1/cache/ 甚至从@987654325 读取,相同的函数和代码可以工作@。现在,由于这适用于外部存储,我认为它可能与权限或 android 如何处理内部存储有关。
【解决方案3】:

试试这个

File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard,"/Newfile.xml");
InputStream is = new BufferedInputStream(new FileInputStream(file));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document dom = db.parse(is); 

【讨论】:

  • 感谢您的回答。我最终做了一些不同的事情,但我认为这是一个比我原来的方法更好的解决方案。我创建了三个函数。 1)下载文件+将内容提取为字符串(在线交互的情况下)2)打开本地保存的文件+将内容提取为字符串(离线交互的情况下)3)一旦我有了字符串解析字符串以获取XML文档。
【解决方案4】:

我最终使用以下内容从字符串中获取文档。字符串可以通过下载文件或者本地读取文件来获取。所以它解决了我遇到的问题。如果有人在将本地文件的内容作为字符串获取方面需要帮助,请在 cmets 中告诉我。从在线服务器获取数据也相当简单。

public final static Document XMLfromString(String xml)
{
    if(xml!=null)
    {
    /* Replace the & in string with &amp (if any) */
        String xmlNew=clearRefs(xml);
        Document doc = null;
    //  Log.v(tag,"After Clearing refs::"+xmlNew);
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        Log.v(tag,"Trying Obtaining Document");
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xmlNew));
            doc = db.parse(is); 
        } catch (ParserConfigurationException e) {
            Log.e(tag,"XML parse error: " + e.getMessage());
            return null;
        } catch (SAXException e) {
            connectionStatus="No data received";
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            Log.e(tag,"I/O exeption: " + e.getMessage());
            connectionStatus="No data received";
            return null;
        }
        return doc;
    }
    else
    {
        connectionStatus="Null string Passed";
        return null;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    相关资源
    最近更新 更多