Java - odczytywanie i przetwarzanie danych z pliku

0

Witajcie, mam pytanie odnośnie odczytywania danych. Przykładowy plik z którego będę pobierał dane, wygląda następująco (jest to plik zawierający informacje o materiałach użytych dla modelu):

//[TWORZENIE NOWEGO OBIEKTU O PONIŻSZYCH PARAMETRACH]
newmtl lambert2SG
illum 4
Kd 0.00 0.00 0.00
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
map_Kd Chrysanthemum.jpg
Ni 1.00
//[TWORZENIE NOWEGO OBIEKTU O PONIŻSZYCH PARAMETRACH]
newmtl lambert3SG
illum 4
Kd 0.97 0.97 0.97
Ka 0.00 0.00 0.00
Tf 0.08 0.08 0.08
Ni 1.00
// [TWORZENIE NOWEGO OBIEKTU O PONIŻSZYCH PARAMETRACH]
newmtl lambert4SG
illum 4
Kd 1.00 1.00 1.00
Ka 0.00 0.00 0.00
Tf 0.01 0.01 0.01
Ni 1.00
// [TWORZENIE NOWEGO OBIEKTU O PONIŻSZYCH PARAMETRACH]
newmtl phong1SG
illum 4
Kd 0.00 1.00 1.00
Ka 0.00 0.00 0.00
Tf 0.05 0.05 0.05
Ni 1.87
Ks 0.86 0.86 0.86
Ns 18.00
//[TWORZENIE NOWEGO OBIEKTU O PONIŻSZYCH PARAMETRACH]
newmtl phong2SG
illum 4
Kd 1.00 0.00 1.00
Ka 0.00 0.00 0.00
Tf 0.03 0.03 0.03
Ni 1.88
Ks 1.00 1.00 1.00
Ns 22.95

Dla każdego z powyższych "bloków" danych będę tworzył nowy obiekt w którym będę te dane przechowywał. Jak widać parametry nie zawsze przyjmują pojedynczą wartość, oraz może być ich znacznie więcej. Dodatkowo nie zawsze będą występować w tej samej kolejności.Najbardziej oczywistym rozwiązaniem byłoby tutaj zapewne zastosowanie ciągu if-else, ale podejrzewam że nie tędy droga.

    public static void read(String mtlFile) throws IOException {
        FileReader fReader = new FileReader(mtlFile);
        BufferedReader bReader = new BufferedReader(fReader);
        String line = bReader.readLine();

        while(line != null) {

            if(line.startsWith("newmtl")) {
                //...
            } else if(line.startsWith("Kd")) {
                //...  
            } else if(line.startsWith("Ka")) {
                //...  
            }
            
            //...
            
            line = bReader.readLine();
        }
    }

Jaki jest zatem najlepszy i najbardziej poprawny sposób na odczytywania i przetwarzania tego typu danych? Będę wdzięczy za każdą wskazówkę :).

0

Może JSON?

[
    {
        "mtl": "lambert2SG",
        "illum": 4,
        "Kd": [
            0.00,
            0.00,
            0.00
        ],
        "Ka": [
            0.00,
            0.00,
            0.00
        ],
        "Tf": [
            1.00,
            1.00,
            1.00
        ],
        "map_Kd": "Chrysanthemum.jpg",
        "Ni": 1.00
    },
    {
        "mtl": "lambert3SG",
        "illum": 4,
        "Kd": [
            0.97,
            0.97,
            0.97
        ],
        "Ka": [
            0.00,
            0.00,
            0.00
        ],
        "Tf": [
            0.08,
            0.08,
            0.08
        ],
        "map_Kd": null,
        "Ni": 1.00
    }
]

tak to wygląda: https://www.baeldung.com/jackson-object-mapper-tutorial
Możesz też zapisywać obiekty Javy bezpośrednio do pliku, ale wtedy zawartość jest nieczytelna dla człowieka.

0

Może być jakaś prosta maszyna stanów na switch-u, żeby orientować się kiedy następuje nowy blok "newmtl" i wiedzieć kiedy stworzyć nowy obiekt materiału i dodawać do niego poszczególne parametry.

enum State {NEWMTL, PARAMS, COMMENT, etc.};

State state = State.NEWTML;

loop:
 switch(state) {
 case NEWMTL:
       - read line ("newmtl <mtlname>")
       - create MtlObject
       state = PARAMS; //next state
 case PARAMS:
       - read line/decode line
       if (Ka, Kd, etc.)
           update mtlobject
       else
           state = NEWMTL; //next state
 }

Do tego możesz zrobić jakiś prosty Lexer, który będzie czytał plik i usuwał komentarze i wypluwał tokeny dla parsera, czyli już wstępnie przetworzone pojedyncze słowa na stringi, floaty, inty, etc:

class Token {
   TokType type; // NEWMTL, STRING, FLOAT, ...
   string s;
   float f;
   int i;
}

Pozwoli to na uproszczenie samego parsera. Będzie on bardziej przejrzysty i łatwy w zrozumieniu, kiedy zredukuje się poziom zagdnieżdżeń if-ów.

Oczywiście to są tylko takie luźne wskazówki, na pewno nie jest to najlepszy czy poprawny sposób o ile takowy w ogóle istnieje. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1