【问题标题】:StringBuilder - Append method stop working at a certain pointStringBuilder - Append 方法在某个点停止工作
【发布时间】:2016-09-27 10:47:57
【问题描述】:

我正在处理一个小项目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,以便正确调试代码。

【问题讨论】:

  • 抱歉,我自己向我解释并删除了我的评论,
  • 您能发布示例数据吗?
  • 我放了一个示例数据的链接。它太大了,无法将其插入我的问题中。
  • 你的“intrestingElements”是什么,我可以用这个单一的转储重现错误吗?
  • 我添加了重现问题的信息。有趣的元素是“page”、“title”和“text”

标签: java eclipse debugging stringbuilder stax


【解决方案1】:

找到星座,但无法重现:

稍微修改了代码:

        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;                

没有 AssertionError 但有输出

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.

【讨论】:

  • 这是我身边@turo 的一个新手错误,导致了这个问题。非常抱歉,非常感谢您的帮助!
【解决方案2】:

这是我的一个大错误,因为我不知道Eclipse 在调试模式下如何处理String 变量。 Append 工作得很好,但是字符串太大而看不到它,在这种情况下,Eclipse 会显示字符串直到某个点,然后显示“...”。

我选择了textBuffer 变量的值来改变它,试图查看真正的值,并且值就在那里,文件的完整字符串,从第一个字符到最后一个字符。

非常感谢 @turo 为我提供的巨大帮助。

【讨论】:

猜你喜欢
  • 2017-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-04
  • 2018-04-29
  • 2017-04-05
  • 1970-01-01
  • 2016-09-08
相关资源
最近更新 更多