最大 200,000 行の長さの約 100 個の XML ファイルから最初の 15 行を読み取る必要があります。これを効率的に行うためにBufferedReaderのようなものを使用する方法はありますか? この質問で概説されている手順では、DocumentBuilder.parse(String)
; これにより、ファイル全体を一度に解析しようとします。
編集: 最初の 15 要素には、テーブルに解析したいファイルに関するメタデータ (ページ名、最終編集日など) が含まれています。
最大 200,000 行の長さの約 100 個の XML ファイルから最初の 15 行を読み取る必要があります。これを効率的に行うためにBufferedReaderのようなものを使用する方法はありますか? この質問で概説されている手順では、DocumentBuilder.parse(String)
; これにより、ファイル全体を一度に解析しようとします。
編集: 最初の 15 要素には、テーブルに解析したいファイルに関するメタデータ (ページ名、最終編集日など) が含まれています。
これがおそらくあなたがやりたいことです-コメントに書いたように、SAXパーサーを使用し、停止の条件が満たされたときにこれを使用します
SAX による xml ドキュメントの解析をいつでも停止するには?
編集:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<first>
<inner>data</inner>
</first>
<second>second</second>
<third>third</third>
<next>next</next>
</root>
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ReadXmlUpToSomeElementSaxParser extends DefaultHandler {
private final String lastElementToRead;
public ReadXmlUpToSomeElementSaxParser(String lastElementToRead) {
this.lastElementToRead = lastElementToRead;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// just for showing what is parsed
System.out.println("startElement: " + qName);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (lastElementToRead.equals(qName)) {
throw new MySaxTerminatorException();
}
}
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
try {
saxParser.parse("src/test.xml", new ReadXmlUpToSomeElementSaxParser("second"));
} catch (MySaxTerminatorException exp) {
// nothing to do, expected
}
}
public class MySaxTerminatorException extends SAXException {
}
}
startElement: root
startElement: first
startElement: inner
startElement: second
なぜそれが良いのですか?一部のアプリケーションがあなたを送信できるという理由だけで
<?xml version="1.0" encoding="UTF-8"?>
<root>
<first><inner>data</inner></first>
<second>second</second>
<third>third</third>
<next>next</next>
</root>
行指向のアプローチは失敗します...
達成するために必要なビジネスロジックに基づいて条件を定義できることを示すために、要素をカウントしないパーサーを提供しました...
要素内のデータの読み込みにはcharacter()
メソッドを使用できますが、
SAX パーサーは、連続するすべての文字データを 1 つのチャンクで返すか、複数のチャンクに分割する場合があります。
JavaDocで詳細を読む
ストリーミング XML パーサーを調べることをお勧めします。ストリーミング API の使用例は、明らかにメモリに収まらない数百 GB のファイルの読み取りにまで及びます。
Java では、StAX API はネイティブ SAX API の (かなり大きな) 進化形です。「オンザフライ」の解析に関するチュートリアルをご覧ください。
これは、lines 変数に 15 行分のデータが格納されるまで (ファイルが小さい場合は 15 行未満)、ファイルを 1 行ずつ読み取る簡単なソリューションです。
File f = new File("your path");
BufferedReader br = null;
String lines = "";
try
{
br = new BufferedReader(new FileReader(f));
String line = null;
int lineCount = 0;
while((line = br.readLine()) != null)
{
lineCount++;
lines += line + "\n";
if(lineCount == 15) break;
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{br.close();}catch(Exception e){}
}
以下のように手で読んだほうがいいです。あなたの場合、DOMパーサーは高価になります。本当にxmlを解析してノードを抽出/挿入したい場合は、SAXパーサーを使用できます。
try (BufferedReader br = new BufferedReader(new FileReader("C:\\testing.txt")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
}