在多条目文本文件

时间:2015-12-24 11:48:42

标签: java swing jtextarea bufferedwriter

我有一个软件可以将其数据存储在多个嵌套数据对象中。在保存此项目数据时,每个实例都会获得一个out句柄(BufferedWriter)并写入自己的数据。大多数数据是单行的,没有问题,但有一些来自JTextAreas的多行字符串。为了存储它们,我编写了一个子方法multiLineWriter(),它将字符串拆分为单行,写入行数,然后写入单行。理论上。因为它并不总是有效。通常它将行计数写为1,但随后写出两行。或者它写出1,但写出两行文本和空行。它不可靠。将项目加载回来后,通常会销毁完整的数据。 typcal对象保存块如下所示:

    // *** write data to file
public void writeDataFile(BufferedWriter out) {
    try {
        out.write(""+getHeadline() );
        out.newLine();
        out.write(""+getStartDateAsString() );
        out.newLine();
        out.write(""+getEndDateAsString() );
        out.newLine();
        out.write(""+getPlaceIndex() );
        out.newLine();
        multiLineWriter(out, getDescription() );
    } catch(Exception e) {}
}

// *** read data from File
public void readDataFile(BufferedReader in) {
    try {
        setHeadline(in.readLine());
        setStartDateAsString(in.readLine());
        setEndDateAsString(in.readLine());
        setPlaceIndex(in.readLine());
        setDescription(multiLineReader(in));
    } catch(Exception e) {}
}

多线作家/读者看起来像这样:

public void multiLineWriter(BufferedWriter out, String areaText) {
    try {
        String ls = System.getProperty("line.separator");
        String[] lines = areaText.split(ls);
        int lineCount = lines.length;
        out.write(""+lineCount);
        out.newLine();
        for(int i = 0;i<lineCount;i++) {
            out.write(lines[i]);
            out.newLine();
        }
    } catch(Exception e) {}
}
public String multiLineReader(BufferedReader in) {
    String targetString = "";
    try {
        String ls = System.getProperty("line.separator");
        int lineCount = Integer.parseInt(in.readLine());
        for(int i = 0;i<lineCount;i++) {
            targetString = targetString + in.readLine() + ls;
        }
    } catch(Exception e) {}
    return targetString;
}

如上所述,lineCount通常为1,但循环似乎要两次或更多次,因为我有时在数据文件中的1之后有两三行。 这对项目来说不可靠。您是否知道如何更改multiLineWriter / reader以可靠地存储和读取数据? JTextArea保存方法不适用于此组合数据文件格式。 非常感谢并祝圣诞快乐:-) -Frankie

修改和更多信息:

感谢您的评论。我知道我必须让它更清楚。 DaveyDaveDave我将从数据文件中添加一个exerpt。 ControlAltDel我写满意。属性是整个数据文件的好方式。因为我对大多数时候看到的旧式都很好,所以我坚持这一点。将当前项目更改为属性是很多手工... StanislavL我重用了。我有Project Object,它创建了out。然后将此out传递给具有子对象的多个对象,有时以循环方式传递,并且每个人都将数据写入此单个对象。写完所有数据后,项目对象当然会刷新并关闭流。在这种情况下,空异常没有问题,因为没有异常(因此在堆栈跟踪中没有任何内容可以分析)。它不是一个例外问题,而是一个逻辑问题。 mKorbel我在上面输错了,现在就改了。 JTextArea读/写不是一个好选择。在保存文件时,数据不在JTextArea中,而是在字符串中,这是在运行时期间从JTextArea中保存的。要使用JtextArea的write方法,我需要将字符串恢复到该区域,然后使用write方法。由于数百个描述对象,我需要在保存过程中执行这一百次。听起来不太好。另一方面,我确信read方法不起作用,因为它将在数据文件中读取到最后并且不会处理数据文件中的嵌套数据结构。谢尔盖:人类可读也不错。目前这有助于我在保存过程后手动更正值,所以我不会丢失任何数据(我现在这是愚蠢的,但它的工作原理:-) 简而言之:我想我的字符串的split方法和字符串数组中字符串的内容有问题。

问题应该更清楚。我有这个JTextArea。它就像数据集显示中的一个字段(它是一个主要管理数百人和地方的小型私人家谱程序)。许多数据对象都有描述字段。当您更改显示中的人员(例如String personDescription)时,JTextArea的内容将存储到一个String变量中。您在上面看到的writeDataFile()方法适用于具有描述字段的事件对象。 所以当我写一个文件时,我从一个String写入文件。由于此字符串取自JTextArea,因此它包含您可以在JTextArea中生成的所有新行字符。当使用一个out.write(data)调用存储它时,由于String中可能有新的行字符,因此在结果数据文件中有多行。因此,您无法通过一次in.readLine()调用来阅读所有这些内容。这就是我创建多行作家和读者的原因。但他们没有按预期工作。 在这里,我向您显示结果数据文件的一个exerpt

...
# +++ FileCollection:
0
# +++ ImageCollection:
0
58
true
Surname
Arthur



25.09.1877
1
01.01.1950
6
https://familysearch.org/
1
Bekannt ist, dass er auf dem Friedhof Großbeerenstr. lag.
Bekannt ist auch, dass die Trauzeugen bei der Heirat  Dorothea Surname und Hermann Surname waren. Hermann ist vermutlich ein Bruder von Valerie.
Weitere Informationen gibt es nicht bisher.
# +++ EventCollection:
0
# +++ FileCollection:
0
...

之前和之后有更多数据,但这里是错误的书面数据。它直接位于familysearch.org的链接下方。后面的第一行应该有行数。如果没有文本,那么它将为0,而下一行将是信息##+; + +++ EventCollection:&#39;。如果有一行,则它将为1,下一行将是用于描述的单行文本。或其他数字取决于JTextArea的行数。但正如你所看到的,在这种情况下写了1,但是后面有3(!)行文本。 所以主要的问题似乎是我使用multiLineWriter()中的split方法。

 String ls = System.getProperty("line.separator");
 String[] lines = areaText.split(ls);
 int lineCount = lines.length;

这似乎很关键。因为我在循环中编写了分割的结果数组,所以这个循环必须完成三次?因为我在数据文件中有3行文本。但是lineCount写成1?所以这似乎是错误的。可能是这个字符串没有被拆分,但仍然包含换行符。那不是我想要的。在splittet字符串数组中,不应再有任何换行符(这也会破坏文件写入)。 希望现在能更好地描述这个问题。问题是,如何设计多行编写器和读取器方法来存储和读取这些数据的可靠性。

再次感谢所有人的圣诞节: - )

1 个答案:

答案 0 :(得分:0)

确定。我亲自尝试过。正如我所说,在字符串上使用split方法存在问题。我现在更改了这个以使用扫描仪。为了正确起见,我使用How do I use System.getProperty("line.separator").toString()?中的一些想法。 所以最后我改变了multiLineWrite方法以使用Scanner(来自util包)。它看起来像这样:

public void multiLineWriter(BufferedWriter out, String areaText) {
    List<String> slines = new ArrayList<String>();
    try {
        Scanner sc = new Scanner(areaText);
        while (sc.hasNextLine()) {
            slines.add(sc.nextLine());
        }
        int slineCount = slines.size();
        out.write(""+slineCount);
        out.newLine();
        for(int i = 0;i<slineCount;i++) {
            out.write(slines.get(i));
            out.newLine();
        }
    } catch(Exception e) {}
}

所以现在这对我来说似乎是可靠的。我使用split方法和Scanner方法的并行编写进行了测试,并且split方法具有错误的行数并且扫描程序是正确的。感谢所有人,现在祝新年快乐.. :-) - Frankie