[英]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.