Hiện tại, tôi đang cố gắng sử dụng SAX Parser nhưng khoảng 3/4 thông qua tệp nó hoàn toàn bị đóng băng, tôi đã thử phân bổ bộ nhớ nhiều hơn nhưng không nhận được bất kỳ cải tiến nào.Làm thế nào để phân tích các tệp XML lớn (50 GB) trong Java
Có cách nào để tăng tốc độ này không? Một phương pháp tốt hơn?
Tước nó vào xương trần, vì vậy bây giờ tôi có mã sau và khi chạy trong dòng lệnh, nó vẫn không đi nhanh như tôi muốn.
Chạy nó với "java -Xms-4096m -Xmx8192m -jar reader.jar" tôi nhận được một giới hạn GC overhead vượt xung quanh bài viết 700000
chính:
public class Read {
public static void main(String[] args) {
pages = XMLManager.getPages();
}
}
XMLManager
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;
}
}
PageHandler
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;
}
}
Bạn có chắc chắn rằng những gì "đóng băng" (muốn cho chúng tôi biết thêm chi tiết về điều đó có nghĩa gì cho tình huống của bạn không?) Là trình phân tích cú pháp SAX thay vì một cái gì đó trong mã của bạn? Bạn có giữ các đối tượng trong bộ nhớ bất cứ nơi nào trong ứng dụng của bạn? – Tim
Im chỉ chạy một số xét nghiệm trên nó vào lúc này, nhưng tôi có một cảm giác nó có thể đã được nhật thực đã được đóng băng lên (Stripoped nó để xương trần và nó sitll đóng băng lên). Chạy nó thông qua dòng lệnh tại thời điểm này, giữ cho bạn được đăng. –
Đã thêm một số mã cơ bản chỉ xuất kết quả đầu ra của người đọc vào trong tệp xml –