【发布时间】:2014-12-06 06:47:22
【问题描述】:
目前我正在尝试使用 SAX 解析器,但大约 3/4 的文件完全冻结了,我尝试分配更多内存等但没有得到任何改进。
有什么办法可以加快速度吗?更好的方法?
将其剥离为裸露的骨头,所以我现在有了以下代码,并且在命令行中运行时它仍然没有我想要的那么快。
使用“java -Xms-4096m -Xmx8192m -jar reader.jar”运行它,我得到超过文章 700000 附近的 GC 开销限制
主要:
public class Read {
public static void main(String[] args) {
pages = XMLManager.getPages();
}
}
XML 管理器
public class XMLManager {
public static ArrayList<Page> getPages() {
ArrayList<Page> pages = null;
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
File file = new File("..\\enwiki-20140811-pages-articles.xml");
PageHandler pageHandler = new PageHandler();
parser.parse(file, pageHandler);
pages = pageHandler.getPages();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return pages;
}
}
页面处理程序
public class PageHandler extends DefaultHandler{
private ArrayList<Page> pages = new ArrayList<>();
private Page page;
private StringBuilder stringBuilder;
private boolean idSet = false;
public PageHandler(){
super();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
stringBuilder = new StringBuilder();
if (qName.equals("page")){
page = new Page();
idSet = false;
} else if (qName.equals("redirect")){
if (page != null){
page.setRedirecting(true);
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (page != null && !page.isRedirecting()){
if (qName.equals("title")){
page.setTitle(stringBuilder.toString());
} else if (qName.equals("id")){
if (!idSet){
page.setId(Integer.parseInt(stringBuilder.toString()));
idSet = true;
}
} else if (qName.equals("text")){
String articleText = stringBuilder.toString();
articleText = articleText.replaceAll("(?s)<ref(.+?)</ref>", " "); //remove references
articleText = articleText.replaceAll("(?s)\\{\\{(.+?)\\}\\}", " "); //remove links underneath headings
articleText = articleText.replaceAll("(?s)==See also==.+", " "); //remove everything after see also
articleText = articleText.replaceAll("\\|", " "); //Separate multiple links
articleText = articleText.replaceAll("\\n", " "); //remove new lines
articleText = articleText.replaceAll("[^a-zA-Z0-9- \\s]", " "); //remove all non alphanumeric except dashes and spaces
articleText = articleText.trim().replaceAll(" +", " "); //convert all multiple spaces to 1 space
Pattern pattern = Pattern.compile("([\\S]+\\s*){1,75}"); //get first 75 words of text
Matcher matcher = pattern.matcher(articleText);
matcher.find();
try {
page.setSummaryText(matcher.group());
} catch (IllegalStateException se){
page.setSummaryText("None");
}
page.setText(articleText);
} else if (qName.equals("page")){
pages.add(page);
page = null;
}
} else {
page = null;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
stringBuilder.append(ch,start, length);
}
public ArrayList<Page> getPages() {
return pages;
}
}
【问题讨论】:
-
您确定什么是“冻结”(想向我们提供更多关于这对您的情况意味着什么的详细信息吗?)是 SAX 解析器而不是您的代码中的某些东西?您是否在应用程序的任何地方都将对象保存在内存中?
-
目前我只是在对其进行一些测试,但我有一种感觉,它可能是 Eclipse 冻结了(将其剥离成裸露的骨头,它会冻结)。目前通过命令行运行它,请随时关注。
-
添加了一些基本代码,仅在 xml 文件中输出读者正在阅读的文章
-
在 endElement() 例程结束时清除 StringBuilder。您实际上需要一堆字符串构建器来正确处理嵌套元素。
-
不是 stringBuilder = new StringBuilder();在 startElement 中“清零”了吗?
标签: java xml xml-parsing sax