Home > front end >  Java: How do I iterate through a file with multiple lines, then extract specific lines after filteri
Java: How do I iterate through a file with multiple lines, then extract specific lines after filteri

Time:09-07

Clarification: I have a text file with multiple lines and I want to separate specific lines into fields for an object.

I have been banging my head against a wall for about 3 days now, and I feel as if I'm overthinking this.

import java.io.*;
import java.util.*;
public class ReadFile {

    public static void main(String[] args) throws FileNotFoundException {
        String fileName = null;


        Scanner input = new Scanner(System.in);
        System.out.print("Enter file path: ");
        fileName = input.nextLine();      
        input.close();
        String fileText = readFile(fileName);
        System.out.println(fileText);

    }

    public static String readFile(String fileName) throws FileNotFoundException {
        String fileText = "";
        String lineText = "";

        File newFile = new File(fileName);
        if (newFile.canRead()) {
            try (Scanner scanFile = new Scanner(newFile)) {
                while (scanFile.hasNext()) {
                    lineText = scanFile.nextLine();
                    
                    if (lineText.startsWith(" ")) {

                     }
                    else { 
                        fileText = fileText   lineText   "\n";
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        } else {
            System.out.println("No file found. Please try again.");
        }
        
        return fileText;
    }

}

My goal is to take a file that looks similar to this (this is the whole file, imagine a .txt with exactly this in it):

Name of Person
----
Clothing:
Graphic TeeShirt
This shirt has a fun logo of
depicting stackoverflow and a horizon.
****
Brown Slacks
These slacks reach to the floor and
barely cover the ankles.
****
Worn Sandals
The straps on the sandals are frayed,
and the soles are obviously worn.
----

Then I need to extract the top line (e.g.: "Graphic TeeShirt") as a type of clothing the object is wearing, then "This shirt has a fun [...]" as the description of that object.

I have another .java with setters/getters/constructors, but I can't figure out how to iterate through the text file.

Edit: I know I loop through each line, but I need to create an object that has the person's name as a field, the item name (Graphic TeeShirt) as a field, then the description under the item as the next field. Then the next object will be a new object with person's name as a field, the next item (Brown Slacks) as a field, then the description as a field.

I don't know how to separate the lines in to the fields I need.

CodePudding user response:

As I mentioned, the data file format is lousy, which is the real source of the problem, but your delimiters can be used to help out a little. You might approach the problem this way. Obviously don't dump your code like I've done into main but this might start you off. You still need to separate the clothing names from their descriptions but you should get the idea from the below. You can then start making a pojo out of the data. Pass the path to your data file to this app and look out for the metadata debug outputs of 'Name' and 'Item'.

import java.util.Scanner;
import java.nio.file.Paths;

public class PersonParser {
    public static void main(String[] args) {
        try {
            try (Scanner scPeople = new Scanner(Paths.get(args[0]))) {
                scPeople.useDelimiter("---- ");
                int tokenCount = 0;
                while (scPeople.hasNext()) {
                    String token = scPeople.next();
                    if (tokenCount % 2 == 0) {
                        System.out.printf("Name: %s", token);
                    } else {
                        // Parse clothing
                        Scanner scClothing = new Scanner(token);
                        scClothing.useDelimiter("\\*\\*\\* ");
                        while (scClothing.hasNext()) {
                            String item = scClothing.next();
                            System.out.printf("Item: %s", item);
                        }
                    }
                    tokenCount  ;
                }
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

}

CodePudding user response:

It's not clear what you want to achieve and what is your issue exactly. You said that you can't figure out how to iterate through a text file, so let's dive into this fairly straightforward task.

In general, you have a valid, but the overcomplicated method for reading a file. Modern versions of Java provide a lot simpler methods and it's better to use them (only if you're not implementing some test task to understand how everything is working under the hood).

Please see my example below for reading a file line by line using Java NIO and Streams APIs:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter file path: ");
        String fileName = input.nextLine();
        input.close();
        
        Path path = Paths.get(fileName);
        try (Stream<String> lines = Files.lines(path)) {
            lines.filter(line -> {
                // filter your lines on some predicate
                return line.startsWith(" ");
            });
            // do the mapping to your object
        } catch (IOException e) {
            throw new IllegalArgumentException("Incorrect file path");
        }
    }
}

This should allow you to filter the lines from your files based on some predicate and later to the mapping to your POJO if you intend to do so.

If you have any other issues besides reading the file and filtering its content, please add clarification to your questions. Preferably, with examples and test data.

  • Related