簡體   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