I have a software that stores its data in multible nested data objects. On saving this project data, every instance gets an out handle (BufferedWriter) and writes its own data. Most data is single line and no problem, but there are a few multiline strings that come from JTextAreas. For storing them, I wrote a sub method multiLineWriter(), that splits the string in single lines, writes the number of lines and then the single lines. In theory. Because its not always working. Often it writes out the line count as 1 but then writes out two lines. Or it writes out 1, but writes out two lines with text and an empty line. Its not reliable. After loading the project back, often the complete data is destroyed. A typcal object saving block looks like this:
// *** 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) {}
}
The multline writer/reader looks like this:
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;
}
As said, lineCount often is 1, but the loop seems to go two or more times because I have sometimes two or three lines after the 1 in a datafile. This is not reliable for the project. Do you have an idea how I can change the multiLineWriter/reader to reliably store and read the data? The JTextArea save method does not work in this combined data file format.
__More info: __
Properties are a good style for the whole datafile. Since I was allright with the old style seen above most of the times I am sticking to that. Changing the current project to properties is a lot of handwork.
I reuse the out. I have Project Object, that creates the out. This out is then passed to multiple objects with subobjects, sometimes in loops, and everyone writes it data to this single out. After all data is written the project Object of course flushes and closes the stream. The empty exceptions are no problem in this case, because there are no exceptions (so there is nothing to analyse in a stack trace). Its not an exception problem but a logical problem.
The JTextArea read/write is not a good option. At time of saving the file, the data is not in a JTextArea but in a string, that was saved sometime ago during runtime from a JTextArea. To use the write method of JtextArea I would need to restore the string to the area and then use the write method. Because of hundreds of those description objects I would need to do this hundred of times in a save process. Sounds not well. On the other hand I am sure that the read method would not work, because it would read in the datafile up to the end and wouldn't handle the nested datastructure in the datafile.
Its not bad to be human readable. Currently this is helping me, to manually correct the values after a save process, so I am not loosing any data (I now this is stupid, but it works:-)
To be short: I guess I have a problem with the split method of strings and the content of the strings in the string array.
Problem should be made clearer. I have this JTextArea. It is like one field in a display for datasets (its a little private genealogy program that mainly manages hundreds of persons and places). A lot of dataobjects have a description field. Contents of the JTextArea are stored to one single String variable when you change the person in display for example (String personDescription). The writeDataFile() Method you see above is for an event object, that has a description field, too. So when I write a File, I write from one String to the file. Since this string is taken from the JTextArea, it contains all new line characters that you can produce in a JTextArea. When storing this with one out.write (data) call you have multiple lines in the resulting data file because of possible new line characters in the String. So you can't read all this content back with one in.readLine() call. That's why I created the multiline writers and readers. But they don't work as expected. Here I show you an exerpt from the resulting datafile
...
# +++ 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
...
There is more data before and below, but here is the wrong written data. Its directly below the link to familysearch.org. The first line that follows should have the line count. If there is no text it would have a 0 and the next line would be the info sting '# + EventCollection:'. If there would be one line, it would have a 1 and the next line would be that single line of text for description. Or other numbers depending on the amount of lines from the JTextArea. But as you see, there is written a 1 in this case, but there are 3 (!) Lines of text following. So the main problem seems to be the way I work with the split method in the multiLineWriter().
String ls = System.getProperty("line.separator");
String[] lines = areaText.split(ls);
int lineCount = lines.length;
This seems to be critical. Since I write the resulting array of the split in a loop, this loop must be done three times? Because I have 3 lines of text in the datafile. But the lineCount is written as a 1? So this seems to be wrong. Could be that this string was not splitted, but still contains line break characters. That would not be what I am looking for. And in the array of splittet Strings there should not be any line break characters anymore (that would destroy the file writing, too). Hope the problem is better described now. And the question is, how should the multiline writer and reader method be designed to store and read this data reliable.