繁体   English   中英

Java:如何遍历包含多行的文件,然后在过滤分隔符后提取特定行?

[英]Java: How do I iterate through a file with multiple lines, then extract specific lines after filtering delimiters?

澄清:我有一个包含多行的文本文件,我想将特定行分隔为 object 的字段。

我已经用头撞墙了大约 3 天了,我觉得好像我想多了。

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;
    }

}

我的目标是获取一个看起来与此类似的文件(这是整个文件,想象 a.txt 中正好有这个):

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.
----

然后我需要提取顶行(例如:“Graphic TeeShirt”)作为 object 所穿的衣服类型,然后“这件衬衫很有趣 [...]”作为 object 的描述。

我有另一个.java,带有setter/getter/constructors,但我不知道如何遍历文本文件。

编辑:我知道我遍历每一行,但我需要创建一个 object,其中包含人名作为字段,项目名称(图形 TeeShirt)作为字段,然后项目下的描述作为下一个字段。 然后下一个 object 将是一个新的 object,其中人名作为字段,下一个项目(棕色休闲裤)作为字段,然后是描述作为字段。

我不知道如何将行分隔到我需要的字段中。

正如我所提到的,数据文件格式很糟糕,这是问题的真正根源,但是您的分隔符可以起到一点帮助。 您可能会以这种方式处理问题。 显然不要像我所做的那样将你的代码转储到main中,但这可能会让你开始。 仍然需要将服装名称与其描述分开,但您应该从下面得到这个想法。 然后,您可以开始利用数据制作 pojo。 将您的数据文件的路径传递给此应用程序,并查看“名称”和“项目”的元数据调试输出。

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();
        }
    }

}

以下代码是根据您问题中的详细信息,即:

  1. 您问题中的示例文件是整个文件。
  2. 您要创建具有以下三个属性的对象实例:
    • 人名。
    • 一件衣服的名称。
    • 该项目的描述。

请注意,我没有向用户询问文件名,而是简单地使用硬编码的文件名。 另请注意,以下代码中的toString方法仅用于测试目的。 该代码还使用try-with-resources方法引用

public class ReadFile {
    private static final String DELIM = "****";
    private static final String LAST = "----";
    private String name;
    private String item;
    private String description;

    public void setName(String name) {
        this.name = name;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    public String toString() {
        return String.format("%s | %s | %s", name, item, description);
    }

    public static void main(String[] strings) {
        try (FileReader fr = new FileReader("clothing.txt");
             BufferedReader br = new BufferedReader(fr)) {
            String line = br.readLine();
            String name = line;
            br.readLine();
            br.readLine();
            line = br.readLine();
            String item = line;
            List<ReadFile> list = new ArrayList<>();
            ReadFile instance = new ReadFile();
            instance.setName(name);
            instance.setItem(item);
            line = br.readLine();
            StringBuilder description = new StringBuilder();
            while (line != null && !LAST.equals(line)) {
                if (DELIM.equals(line)) {
                    instance.setDescription(description.toString());
                    list.add(instance);
                    instance = new ReadFile();
                    instance.setName(name);
                    description.delete(0, description.length());
                }
                else {
                    if (instance.getItem() == null) {
                        instance.setItem(line);
                    }
                    else {
                        description.append(line);
                    }
                }
                line = br.readLine();
            }
            if (description.length() > 0) {
                instance.setDescription(description.toString());
                list.add(instance);
            }
            list.forEach(System.out::println);
        }
        catch (IOException xIo) {
            xIo.printStackTrace();
        }
    }
}

运行上述代码会生成以下 output:

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

目前尚不清楚您想要实现什么以及您的问题到底是什么。 您说您不知道如何遍历文本文件,所以让我们深入研究这个相当简单的任务。

通常,您有一个有效但过于复杂的读取文件的方法。 现代版本的 Java 提供了很多更简单的方法,最好使用它们(仅当您没有执行一些测试任务以了解一切如何在幕后工作时)。

请参阅下面的示例,以使用 Java NIO 和 Streams API 逐行读取文件:

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");
        }
    }
}

如果您打算这样做,这应该允许您根据某些谓词过滤文件中的行,然后再映射到您的 POJO。

如果您除了阅读文件和过滤其内容之外还有其他问题,请在您的问题中添加说明。 最好有例子和测试数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM