java - StringBuilder - Append 方法在某个点停止工作

标签 java eclipse debugging stringbuilder stax

我正在处理一个小项目,graphipedia (用于导入维基百科转储),我正在使用 stax 解析器,用于导入维基引用转储。

在该过程的某个时刻,我读取了一些文本字符(在 之间),并且代码对 StringBuilder 变量执行追加方法,但由于某种原因,追加不会向 StringBuilder 变量添加单个字符。

这是代码:

package org.graphipedia.dataimport;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;

import org.codehaus.stax2.XMLInputFactory2;

public abstract class SimpleStaxParser {

    private static final String STDIN_FILENAME = "-";
    private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory2.newInstance();

    private final List<String> interestingElements;

    public SimpleStaxParser(List<String> interestingElements) {
        this.interestingElements = interestingElements;
    }

    protected abstract void handleElement(String element, String value);

    public void parse(String fileName) throws IOException, XMLStreamException {
        if (STDIN_FILENAME.equals(fileName)) {
            parse(System.in);
        } else {
            parse(new FileInputStream(fileName));
        }
    }

    private void parse(InputStream inputStream) throws IOException, XMLStreamException {
        XMLStreamReader reader = XML_INPUT_FACTORY.createXMLStreamReader(inputStream, "UTF-8");
        try {
            parseElements(reader);
        } finally {
            reader.close();
            inputStream.close();
        }
    }

    private void parseElements(XMLStreamReader reader) throws XMLStreamException {
        LinkedList<String> elementStack = new LinkedList<String>();
        StringBuilder textBuffer = new StringBuilder();

        while (reader.hasNext()) {
            switch (reader.next()) {
            case XMLEvent.START_ELEMENT:
                elementStack.push(reader.getName().getLocalPart());
                textBuffer.setLength(0);
                break;
            case XMLEvent.END_ELEMENT:
                String element = elementStack.pop();
                if (isInteresting(element)) {
                    handleElement(element, textBuffer.toString().trim());
                }
                break;
            case XMLEvent.CHARACTERS:
                if (isInteresting(elementStack.peek())) {
                    textBuffer.append(reader.getText());
                }
                break;
            }
        }
    }

    private boolean isInteresting(String element) {
        return interestingElements.contains(element);
    }

}

给我带来一些麻烦的是这一行:

textBuffer.append(reader.getText());

在该行中,reader.getText() 返回以下内容:

lo que pasó, pasó por una razón...

'''Neo''': ¿Y qué razón es esa?

'''Smith''': Yo lo maté, señor Anderson, lo vi morir... Con cierta satisfacción, debo decir. Y luego algo pasó. Algo que sabía que era imposible, pero aún así pasó: usted me destruyó, señor Anderson... Después, cuando supe las reglas, entendí lo que debí haber hecho, pero no lo hice. No podía, fui obligado a quedarme, fui obligado a desobedecer... Y ahora aquí estoy por su culpa, señor Anderson. Por su culpa, ya no soy un agente de este sistema. Por su culpa cambié, me desconecté. Un hombre libre por decir algo, como usted, aparentemente libre.

'''Neo''': ¡Felicidades!

'''Smith''': Gracias... Pero, como sabrá, las apariencias engañan, lo cual me regresa a la razón por la que estoy aquí. No estamos aquí por ser libres. Estamos aquí por no ser libres. No hay razón de escapatoria, ni propósitos de negación. Porque, como sabemos, sin propósitos, no existiríamos...

'''Clones''': Propósito fue lo que nos creó... propósito lo que nos conecta, propósito lo que nos impulsa, lo que nos guía, lo que nos controla, es el propósito lo que define, propósito lo que nos une.

'''Smith''': Estamos aquí por culpa suya, señor Anderson. Estamos aquí para quitarle lo que trató de quitarnos a nosotros ¡Propósito!

[[Categoría:Películas]]

[[en:The Matrix (franchise)]]
[[sl:Matrica]]

执行append方法之前,textBuffer变量的计数值为30643,容量为64254,要添加的文本长度为1352。

可以在以下位置查看解析器正在处理的数据:https://es.wikiquote.org/w/index.php?title=The_Matrix&action=edit (太大了,无法在此发布)

<小时/>

重现此问题的步骤: 获取dump ,下载graphipedia ,解压并使用 maven (mvn package) 构建它,然后从 Eclipse 或类似的 ide 运行 ExtractLinks,以便正确调试代码。

最佳答案

找到了星座,但无法重现:

稍微更改了代码:

        case XMLEvent.CHARACTERS:
            if (isInteresting(elementStack.peek())) {
                int sizeBefore = textBuffer.length();
                String text = reader.getText();
                int textSize = text.length();
                textBuffer.append(text);
                int sizeAfter = textBuffer.length();
                assert sizeBefore + textSize == sizeAfter : "Error occured " + sizeBefore + " " + textSize + " :"
                        + text;
                if (textSize == 1352) {
                    System.out.println(
                            "Size before " + sizeBefore + " textSize " + textSize + " sizeafter " + sizeAfter);
                }
            }
            break;                

没有断言错误,但有输出

Parsing pages and extracting links...
Size before 30643 textSize 1352 sizeafter 31995
...........Size before 0 textSize 1352 sizeafter 1352
...Size before 83963 textSize 1352 sizeafter 85315
.
15309 pages parsed in 0 seconds.

关于java - StringBuilder - Append 方法在某个点停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37511543/

相关文章:

java - 为什么 iso8601 LocalDatetime 仅适用于 UTC 而不适用于本地日期时间?

java - Android:在 View.setSystemUiVisibility(int) 中读取按位运算符 OR

java - 将整数 ArrayList 的值与变量 Integer 进行比较时出错

eclipse - 导入 Eclipse 项目后触发 Gradle 任务

java - Eclipse -> Intellij 转换有哪些好的引用资料/文章/帖子?

c++ - 让主机应用程序在调试时看到 .so 库

java 。限制日期的值

visual-studio - 如何在 Visual Studio 中调试/分析 BSOD 转储?

c - 调试 C Windows 服务中的启动问题

c - 以文本格式打印数字的数字