3

我正在尝试使用 Java 创建一个 XML 文件,它是 GPS 坐标 (GPX) 的集合。每次我从我的 android 设备收到坐标(大约每秒 1 个)时,我都需要将结果附加到现有的 XML 文件中。我正在寻找的输出如下所示,其中 trkpt 元素作为重复项。问题是我不能只将新的 trkpt 添加到文件的末尾,因为它需要在 trkseg 父元素内。

到目前为止,我已经尝试了两种不同的 API,SIMPLEXML 和 JDOM。使用 SIMPLEXML,我无法弄清楚如何将子元素附加到现有文件中,因此我切换到了 JDOM。JDOM 允许我附加 trkpt 元素,如下所示,但是随着文件开始增长,它很快就减慢了程序的用户界面。使用 JDOM,我使用 SAXBuilder 重新打开文件并追加。我认为这个问题是它必须在添加新元素并重写文件之前在内存中复制整个文件。因此,文件越大,设备上的操作要求就越高。我需要一个在写入新数据之前不检查/复制整个文件的解决方案。有没有更有效的方法可以使用 Java 或 Java 的 API 来完成此任务?谢谢你的帮助!

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1">
        <trk>
            <trkseg>
                <trkpt lon="9.860624216140083" lat="54.9328621088893">
                    <ele>228.0</ele>
                </trkpt>
                <trkpt lon="9.860624216140100" lat="54.9328621088754">
                    <ele>234.0</ele>
                </trkpt>
                <trkpt lon="9.860624216140343" lat="54.9328621088678">
                    <ele>227.0</ele>
                </trkpt>
            </trkseg>
        </trk>
</gpx>
4

4 回答 4

0

如果它像这里所说的那么简单,您可以只使用 RandomAccessFile 并寻找文件长度减去几个字节(就在根结束标记之前),然后开始覆盖那里。

于 2012-02-18T18:46:16.790 回答
0

这听起来像是 SAX 的完美应用程序(在包中找到它org.xml.sax);它是用于 XML 访问和操作的流式 API。SAX 为其遇到的每个元素生成事件,允许您将文件复制到新文件,而无需将其解析为大型内存树。当您到达输入文件的末尾时,只需在处理<trkseg>.

当然,您每秒重写此文件的方法本身就值得怀疑。您可以将信息捆绑在更大的部分中吗?您可以将信息转储到单个文件中,并以特定间隔(每 10/30/60 秒)将它们收集到单个文件中。

于 2012-02-18T18:12:43.790 回答
0

我建议将 xml 文件分成 3 个部分。

头文件

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1">
    <trk>
        <trkseg>

正文.xml

<trkpt lon="9.860624216140083" lat="54.9328621088893">
    <ele>228.0</ele>
</trkpt>
<trkpt lon="9.860624216140100" lat="54.9328621088754">
    <ele>234.0</ele>
</trkpt>
<trkpt lon="9.860624216140343" lat="54.9328621088678">
    <ele>227.0</ele>
</trkpt>

尾部.xml

        </trkseg>
    </trk>
</gpx>

现在,每当您获得新数据时,只需将其附加到 body.xml

要读取 xml 文件,请使用 SequenceInputStream,如下所示:

List<InputStream> list = new ArrayList<InputStream>(3);
list.add(new FileInputStream("head.xml"));
list.add(new FileInputStream("body.xml"));
list.add(new FileInputStream("tail.xml"));
InputStream xmlStream = new SequentialInputStream(Collections.enumeration(list));
于 2012-02-19T06:39:12.487 回答
0

在 I/O 方面总是存在瓶颈,尤其是在以重复方式打开/关闭/重新打开文件时。

DOM 处理程序将在每次打开文件时创建一个完整的树结构,但在更改该树时非常有效。

所以首先,你真的需要在每一次交易中打开、修改、保存文件吗?如果不是,则将文件的 DOM 保存在内存中,并通过对 XML 的引用进行更改。当用户退出应用程序或离开视图时保存。

如果您确实需要在每次滴答时保存文件,您仍然可以将 DOM 保存在内存中,并且只在每次滴答时将其保存到磁盘。

如果您需要在每次滴答时打开/保存/重新打开文件,请不要使用任何 XML 库 - 只需使用标准 FileWriter 或类似工具,手动更改内容 - 但仍然很难维护如果文件变得非常大,则性能。

于 2012-02-18T18:02:10.640 回答