[英]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();
}
}
}
以下代碼是根據您問題中的詳細信息,即:
請注意,我沒有向用戶詢問文件名,而是簡單地使用硬編碼的文件名。 另請注意,以下代碼中的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.