3

GPS座標(GPX)のコレクションであるJavaを使用してXMLファイルを作成しようとしています。Androidデバイスから座標を受け取るたびに(約1秒に1回)、結果を既存のXMLファイルに追加する必要があります。私が探している出力は、繰り返し項目としてtrkpt要素を使用して以下に示されています。問題は、trksegの親要素内にある必要があるため、ファイルの最後に新しいtrkptを追加できないことです。

これまで、SIMPLEXMLとJDOMの2つの異なるAPIを試しました。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

xmlファイルを3つの部分に分割することをお勧めします。

head.xml

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

body.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>

tail.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 に答える
0

これは SAX の完璧なアプリケーションのように思えます (パッケージに含まれていますorg.xml.sax)。これは、XML へのアクセスと操作のためのストリーミング API です。SAX は、検出したすべての要素に対してイベントを生成するため、ファイルを解析して大きなメモリ内ツリーにすることなく、ファイルを新しいファイルにコピーできます。入力ファイルの最後に到達したら、 の終了タグを処理する前に、必要に応じて新しい要素を追加します<trkseg>

もちろん、このファイルを毎秒書き換えるというあなたのアプローチは、それ自体が疑わしいように思えます。情報をより大きなセグメントにまとめることができますか? 情報を単一のファイルにダンプし、特定の間隔 (10/30/60 秒ごと) でそれらを単一のファイルに収集できます。

于 2012-02-18T18:12:43.790 に答える