Четене на множество записи от плосък файл в Java

Имам дъмп на текстов файл, който трябва да конвертирам във файл с разделители. Файлът съдържа серия от "записи" (поради липса на по-добра дума), форматирани по следния начин:

User: abc123 
Date: 7/3/12
Subject: the foo is bar
Project: 123456
Problem: foo bar in multiple lines of text
Resolution: foo un-barred in multiple lines of text

User: abc123 
Date: 7/3/12
Subject: the foo is bar
Project: 234567
Problem: foo bar in multiple lines of text
Resolution: foo un-barred in multiple lines of text

...

Крайният ми резултат е да получа плосък файл с разделени стойности. Използвайки записите по-горе, ще видим:

abc123;7/3/12;the foo is bar;123456;foo bar in multiple lines of text;foo un-barred in multiple lines of text
abc123;7/3/12;the foo is bar;234567;foo bar in multiple lines of text;foo un-barred in multiple lines of text

Кодът се появява по-долу и след това проблемът, който изпитвам.

    import java.util.*;
import java.io.*;
import java.nio.file.*;
//
public class ParseOutlookFolderForSE
{
        public static void main(String args[])
        {
            String user = "";
            String PDLDate = "";
            String name = "";
            String PDLNum = "";
            String problemDesc = "test";
            String resolutionDesc = "test";
            String delim = ";";
            int recordCounter = 0;
            //
            try
            {
                Path file = Paths.get("testfile2.txt");
                FileInputStream fstream = new FileInputStream("testfile2.txt");
               // Get the object of DataInputStream
                /* DataInputStream in = new DataInputStream(fstream);  */
                BufferedReader br = new BufferedReader(new InputStreamReader(fstream));  //Buffered Reader
                String inputLine = null;     //String
                StringBuffer theText = new StringBuffer();  //StringBuffer
// problem: output contains last record ONLY. program is cycling through the entire file, overwriting records until the end.
// add a for loop based on recordCounter
                for(recordCounter=0;recordCounter<10;recordCounter++)
                {
                while((inputLine=br.readLine())!=null)
                {
                    if(inputLine.toLowerCase().startsWith("from:"))
                    {

                /*      recordCounter = recordCounter++;    */  // commented out when I added recordCounter++ to the for loop
                        user = inputLine.trim().substring(5).trim();
                    }
                    else
                    if(inputLine.toLowerCase().startsWith("effective date"))
                    {

                        PDLDate = inputLine.trim().substring(15).trim();
                    }
                    else
                    if(inputLine.toLowerCase().startsWith("to:"))
                    {

                        name = inputLine.trim().substring(3).trim();
                    }
                    else
                    if(inputLine.toLowerCase().startsWith("sir number"))
                    {

                        PDLNum = inputLine.trim().substring(12).trim();
                    }
                }      //close for loop
                }   // close while
                System.out.println(recordCounter + "\n" + user + "\n" + name + "\n" + PDLNum + "\n" + PDLDate + "\n" + problemDesc + "\n" + resolutionDesc);
                System.out.println(recordCounter + ";" + user + ";" + name + ";" + PDLNum + ";" + PDLDate + ";" + problemDesc + ";" + resolutionDesc);
                String lineForFile = (recordCounter + ";" + user + ";" + name + ";" + PDLNum + ";" + PDLDate + ";" + problemDesc + ";" + resolutionDesc + System.getProperty("line.separator"));
                System.out.println(lineForFile);
                try
                {
                    BufferedWriter out = new BufferedWriter(new FileWriter("testfileoutput.txt"));
                    out.write(lineForFile);
                    out.close();
                }
                catch (IOException e)
                {
                    System.out.println("Exception ");
                }
            } //close try
            catch (Exception e)
            {
                System.err.println("Error: " + e.getMessage());
            }
        }

    }

Крайният ми резултат е САМО последният запис. Вярвам, че това, което се случва, е, че програмата чете всеки ред, но само ПОСЛЕДНИЯТ не се презаписва със следващия запис. Има смисъл. Така че добавих FOR цикъл, увеличавайки с 1 if(inputLine.toLowerCase().startsWith("user:")) и извеждайки променливата на брояча с моите данни, за да проверя какво се случва.

Моят FOR цикъл започва след стъпка 3 в моя псевдокод...след BufferedReader, но преди моите IF изрази. Прекратявам го, след като пиша във файла в стъпка 6. Използвам for(recCounter=0;recCounter<10;recCounter++) и докато получавам десет записа в моя изходен файл, всички те са екземпляри на ПОСЛЕДНИЯ запис на входния файл, номерирани 0-9.

Оставяйки цикъла for на същото място, го модифицирах да чете for(recCounter=0;recCounter<10;) и поставих увеличението на recCounter В рамките на оператора IF, увеличавайки всеки път, когато редът започва с User:. В този случай също получих десет записа в моя изходен файл, те бяха десет екземпляра на последния запис във входния файл и всички броячи са 0.

РЕДАКТИРАНЕ: Като се има предвид как е форматиран файлът, ЕДИНСТВЕНИЯТ начин да се определи w=един запис от следващия е последващо копие на думата "Потребител:" в началото на реда. Всеки път, когато се случи, до СЛЕДВАЩИЯ път, когато се случи, това представлява единичен запис.

Изглежда, че не настройвам правилно своя „recCounter“ или не интерпретирам резултатите от това, което Е зададено като „започване на нов запис“.

Някой има ли някакви предложения как да чета този файл като множество записи?


person dwwilson66    schedule 03.07.2012    source източник
comment
имате 2 реда, отбелязани с '} //close for loop', но само 1 for loop! Кодът също не се компилира за мен, без да премахна един от тях. Опитайте да премахнете първия и ни уведомете дали това оправя нещата.   -  person Colin D    schedule 03.07.2012
comment
Също така не съм сигурен защо всички append() работят. Класът Java String няма метод append(). Вместо това трябва да работите със StringBuilder. Както @ColinD спомена, вие също имате допълнително }, което няма смисъл. Където имате //close for цикъл и //close for while коментари.   -  person Chris911    schedule 03.07.2012
comment
@ColinD Кодът е актуализиран до правилната версия...проблемът с твърде много отворени прозорци! Кодът все още няма да работи според очакванията - само последният запис.   -  person dwwilson66    schedule 03.07.2012
comment
@Chris911 append() се основава на този проблем stackoverflow.com/questions/11311452/, който имах по-рано днес. Дадоха ли ми лош съвет за това?   -  person dwwilson66    schedule 03.07.2012
comment
@dwwilson66 Chris911 посочваше, че извиквате добавяне към низ. Вашият публикуван въпрос, предложи използването му на StringBuilder.   -  person Colin D    schedule 03.07.2012
comment
@ColinD Да...разбрах това и все още трябва да поправя този проблем; ето защо кодът за добавяне е изтрит, докато разбера какво бъркам във файла за четене/запис. Благодаря за пояснението   -  person dwwilson66    schedule 03.07.2012


Отговори (2)


Добре, вашият псевдокод трябва да изглежда нещо подобно:

declare variables
open file
while not eof
  read input
  if end of set
    format output
    write output
    clear variables
  figure out which variable
  store in correct variable
end-while

Може да има трик да разберете кога сте завършили един комплект и можете да започнете следващия. Ако наборът трябва да бъде прекратен с празен ред, както се вижда от вашия пример, тогава можете просто да проверите за празния ред. Иначе откъде знаеш? Наборът винаги ли започва с "потребител"?

Освен това не забравяйте да напишете последния запис. Не искате да оставяте ненаписани неща във вашия буфер/таблица.

person Jay    schedule 03.07.2012
comment
Мисля, че краят на зададената част е това, което ми липсва; Ще се забъркам малко с това. Да, наборът ВИНАГИ започва с user: и това е почти единственият надежден маркер във файла. Изясних въпроса, за да добавя тази бележка. - person dwwilson66; 03.07.2012

От вашето описание звучи, че случаят е следният: вие всъщност не пишете изходните низове, докато ги попълвате, а вместо това правите цялото писане в края. Не звучи така, сякаш запазвате изходните низове извън цикъла и така всеки път, когато намерите запис, презаписвате изходния низ, който сте изчислили преди това.

Трябва да проверите дали всъщност пишете във файла, след като всеки запис бъде намерен и има създаден изходен низ.

Без да публикувам вашия код, не съм сигурен, че мога да ви помогна много повече.

person Colin D    schedule 03.07.2012
comment
това също подозирам, че се случва, но не мога да разбера къде да го направя. Кодът обаче беше публикуван...така че ако имате още информация, ще се радвам да науча какво имате! - person dwwilson66; 03.07.2012