mas-designs
mas-designs

Reputation: 7556

Read file in java over more than one line

Hy,

I'm expiriencing logical troubles at reading a file, line for line. I know you can do this with BufferedReader, but sometimes I have "values" which are written in more lines, which would be important.

Sample of the file im reading:

   <#FIELD NAME = DESC> Some text that goes

        over multiple lines

        which is needed</#FIELD>

    <#FIELD NAME = TEMP> some values are just a single line</#FIELD>

I need to parse the Field Name, which would be TEMP or DESC like above, and then extract the value between those brackets <#FIELD NAME =DESC>important values </#FIELD>. But I'm not really sure how to "recognize" that an entry has a multiple line value or a single value line and then save it to a variable, when using BufferedReader.

I would really appreciate any hint or example to direct me into the right direction !

Because reading it line for line, did not help me progress... I will not post the whole code as I think there is a more easier way to read it and you will get an idea of what I've done so far by this little snippet.

if (line.contains("<#FIELD NAME = AUTOR>"))
{
    String autor = line.substring(line.indexOf(">") + 1, line.indexOf("</#"));
    metaData.setAutor(autor.trim());
}
else if (line.contains("<#FIELD NAME = DOKUMENTNR>"))
{
    String dokumentnr = line.substring(line.indexOf(">") + 1, line.indexOf("</#"));
    metaData.setDoukumentnr(dokumentnr.trim());
    ...

Upvotes: 0

Views: 1258

Answers (5)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136122

My version:

    Pattern p = Pattern.compile("<#FIELD.+</#FIELD>", Pattern.DOTALL);
    Scanner s = new Scanner(new File("test.txt"));
    for(;;) {
        String field = s.findWithinHorizon(p, 0);
        if (field == null) {
            break;
        }
        // here you got a full #FIELD element, parse it
        System.out.println(field);
    }

Upvotes: 0

Kami
Kami

Reputation: 19447

try something like

public string ReadField(BufferedReader reader) 
{
    string line = reader.readLine();
    while (line.indexOf("</#FIELD>") == -1)
    {
        line += reader.readLine(); // This does not preserve line breaks
    }

    return line;
}

In the original code, something like

string line = ReadField(myReader); // This reads up to the next field

if(line.contains("<#FIELD NAME = AUTOR>")){
   String autor = line.substring(line.indexOf(">")+1,line.indexOf("</#"));
   metaData.setAutor(autor.trim());
} else if(line.contains("<#FIELD NAME = DOKUMENTNR>")) {
   String dokumentnr = line.substring(line.indexOf(">")+1,line.indexOf("</#"));
   metaData.setDoukumentnr(dokumentnr.trim());
}

Upvotes: 1

Pawel Solarski
Pawel Solarski

Reputation: 1048

while((line=reader.readLine()) != null){
    if(isDescOrTemp(line)){
        if(line.endsWith("</#FIELD>"){
           //one line field
        } else
        while(!line.endsWith("</#FIELD>"){
            //read more lines
            line=reader.readLine();
            //store line somewhere
        }
    }
}

Upvotes: 1

auselen
auselen

Reputation: 28087

In my understanding, if you don't have an hierarchical data (like a tree), it means you have a list, so you are looking for a way to split it. Normally you should write a clean parser but if that's not the case you can try to hack your way.

String s = "<#FIELD NAME = DESC> Some text that goes\nover multiple lines\nwhich is needed</#FIELD>\n<#FIELD NAME = TEMP> some values are just a single line</#FIELD>";
String[] fs = s.split("<#FIELD NAME = ");
for (String f : fs) {
    System.out.println(f);
}

produces

DESC> Some text that goes
over multiple lines
which is needed</#FIELD>

TEMP> some values are just a single line</#FIELD>

After this you need to clean up your result strings by removing the </#FIELD> at the end and reading the key at the beginning.

Upvotes: 1

Azodious
Azodious

Reputation: 13882

You can follow a pseudocode like below:

While(!EOF)
{
    string line = readLine();
    while( !EOF && ! line.contains("</#FIELD>"))
    {
        line += readLine();
    }
    // Here you get a line with matching `begin` and `end`

    // ... do operations as needed

    // reset line
    line = "";
}

Upvotes: 0

Related Questions