For循环将数据写入文件Java
For loop to write data to file Java
我需要根据代码中的Javadoc实现一个名为saveWorksToFile
的方法。写入文件的输出格式应为以下模式:
其中ARTIST_NAME为艺术家姓名,NUM_WORKS为作品数量
该艺术家的名称,WORK_1、WORK_2 等是的 toString 表示形式
该艺术家的每一件作品。
最后一个作品后面不应该有行分隔符。
如果一个艺术家没有作品,那么上面格式的前三行应该
被写入,其中“-----”行后面有一个行分隔符。
这是我的代码:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
public class Artist {
static class Work {
String name; // e.g. "Mona Lisa"
int yearCreated; // e.g. 1506
String medium; // e.g. "Oil on poplar panel"
public Work(String name, int yearCreated, String medium) {
this.name = name;
this.yearCreated = yearCreated;
this.medium = medium;
}
public String getName() { return name; }
public int getYearCreated() { return yearCreated; }
public String getMedium() { return medium; }
@Override
public String toString() {
return name + "|" + yearCreated + "|" + medium;
}
}
private String name; // e.g. "Henri Matisse"
private List<Work> works = new ArrayList<>();
public Artist(String name) {
this.name = name;
}
public void addWork(Work work) {
this.works.add(work);
}
/**
* Writes the toString representation of each of this artist's works to the
* given writer. Also writes header lines containing the artist's name and
* number of works.
*
* If an IOException occurs, the message "IOException occurred" should be
* printed to System.out.
*
* @param writer writer to write this artist's works to
*/
public void saveWorksToFile(Writer writer) {
// write your code here
try {
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(this.name);
buffer.newLine();
buffer.write("works: " + this.works.size());
buffer.close();
}
catch (IOException e) {
System.out.println("IOException occurred");
}
}
}
我遇到了这些错误:
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
我很难换行,我尝试了 \n
和 newLine()
方法,但它不起作用。并且还显示列表中的作品数量应该是正确的。至于循环,我想在这种情况下我应该使用for循环来循环艺术作品。
任何提示/帮助都会很棒,谢谢!
您可以使用 json 格式轻松保存您的数据并像这样组织
public void saveWorksToFile(OutputStreamWriter writer) {
// write your code here
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("ARTIST_NAME",this.name);
jsonObject.put("NUM_WORKS",this.works.size());
for (int i=0;i<works.size();i++) {
jsonObject.put("work_" + i, works.get(i).toString());
// you can save work as a byte array or json string so you could easily import the data back
}
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(jsonObject.toString()+"\n");
buffer.close();
}
catch (IOException | JSONException e) {
System.out.println("IOException occurred");
}
}
public Artist readFromFile(File file){
Artist artist = null;
FileReader fileReader = null;
String line= null;
BufferedReader bufferedReader;
try {
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
line = bufferedReader.readLine();
while (line != null){
line += "\n";
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(line);
String name = jsonObject.get("ARTIST_NAME").toString();
int works_num = Integer.parseInt(jsonObject.get("NUM_WORKS").toString());
// here you can import the works as a string.
artist = new Artist(name);
} catch (JSONException e) {
e.printStackTrace();
}
line = bufferedReader.readLine();
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return artist;
}
我的建议是你分开类,有时很难找出问题。我是这样分开的。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Artist {
private String name; // e.g. "Henri Matisse"
private List<Work> works = new ArrayList<>();
public Artist(String name) {
this.name = name;
}
public void addWork(Work work) {
this.works.add(work);
}
public void saveWork(){
try{
BufferedWriter writer = new BufferedWriter(
new FileWriter("path where want to save"));
writer.write(this.name);
writer.newLine();
writer.write("works: " + this.works.size());
writer.newLine();
this.works.forEach(work -> {
try {
writer.write(work.name);
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
});
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Work {
String name; // e.g. "Mona Lisa"
int yearCreated; // e.g. 1506
String medium; // e.g. "Oil on poplar panel"
public Work(String name, int yearCreated, String medium) {
this.name = name;
this.yearCreated = yearCreated;
this.medium = medium;
}
public String getName() { return name; }
public int getYearCreated() { return yearCreated; }
public String getMedium() { return medium; }
@Override
public String toString() {
return name + "|" + yearCreated + "|" + medium;
}
}
public class Main {
public static void main(String[] args) {
Work work1 = new Work("Fast1",2019,"ss");
Work work2 = new Work("Fast2",2019,"ss");
Artist artist = new Artist("Artist_Tom_Cruise");
artist.addWork(work1);
artist.addWork(work2);
artist.saveWork();
}
}
下面是方法 saveWorksToFile
的代码。这是我更改的问题中唯一的代码部分。 (代码后的注释。)
public void saveWorksToFile(Writer writer) {
try {
writer.write(this.name);
writer.write(System.lineSeparator());
writer.write("works: " + this.works.size());
writer.write(System.lineSeparator());
writer.write("---");
writer.write(System.lineSeparator());
boolean first = true;
for (Work work : works) {
if (first) {
first = false;
}
else {
writer.write(System.lineSeparator());
}
writer.write(work.toString());
}
}
catch (IOException e) {
System.out.println("IOException occurred");
}
}
您不应该将 Writer
参数包装在 BufferedWriter
中。通常,对于任何方法,您通常都不需要强制转换参数。因此,在上面的代码中,我只使用了classWriter
的方法。另请注意,我没有关闭 Writer
因为那应该留给调用方法 saveWorksToFile
.
的代码
为了写行分隔符,我调用了classjava.lang.System
的方法lineSeparator
。
为了每行打印一个艺术家的所有作品,我使用了一个循环。
为了确保艺术家作品列表中的最后一个条目没有行分隔符,第一个作品没有行分隔符,后面的每个作品都有前面的行分隔符。
这是我写的一个方法来测试上面的代码。它使用 class java.io.StringWriter
是 Writer
的子 class 因为 class Writer
是抽象的并且没有 public 构造函数。通常,您不能实例化抽象 class。您需要使用具体的 subclass。我使用 StringWriter
以便能够轻松地将其内容打印到屏幕上。如果要写入实际文件,可以使用 class java.io.FileWriter
。
/**
* import java.io.StringWriter
*/
public static void main(String[] args) {
Artist artist = new Artist("Vincent van Gogh");
StringWriter sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
System.out.println();
artist = new Artist("Claude Monet");
Work work = new Work("Bridge over a Pond of Water Lilies", 1899, "Oil on canvas");
artist.addWork(work);
work = new Work("Impression, Sunrise", 1872, "Oil on canvas");
artist.addWork(work);
sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
System.out.println();
artist = new Artist("Henri Matisse");
work = new Work("Woman with a Hat", 1905, "Oil on canvas");
artist.addWork(work);
sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
}
这是我在 运行 上述 main
方法时得到的输出。
Vincent van Gogh
works: 0
---
Claude Monet
works: 2
---
Bridge over a Pond of Water Lilies|1899|Oil on canvas
Impression, Sunrise|1872|Oil on canvas
Henry Matisse
works: 1
---
Woman with a Hat|1905|Oil on canvas
我需要根据代码中的Javadoc实现一个名为saveWorksToFile
的方法。写入文件的输出格式应为以下模式:
其中ARTIST_NAME为艺术家姓名,NUM_WORKS为作品数量 该艺术家的名称,WORK_1、WORK_2 等是的 toString 表示形式 该艺术家的每一件作品。
最后一个作品后面不应该有行分隔符。
如果一个艺术家没有作品,那么上面格式的前三行应该 被写入,其中“-----”行后面有一个行分隔符。
这是我的代码:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
public class Artist {
static class Work {
String name; // e.g. "Mona Lisa"
int yearCreated; // e.g. 1506
String medium; // e.g. "Oil on poplar panel"
public Work(String name, int yearCreated, String medium) {
this.name = name;
this.yearCreated = yearCreated;
this.medium = medium;
}
public String getName() { return name; }
public int getYearCreated() { return yearCreated; }
public String getMedium() { return medium; }
@Override
public String toString() {
return name + "|" + yearCreated + "|" + medium;
}
}
private String name; // e.g. "Henri Matisse"
private List<Work> works = new ArrayList<>();
public Artist(String name) {
this.name = name;
}
public void addWork(Work work) {
this.works.add(work);
}
/**
* Writes the toString representation of each of this artist's works to the
* given writer. Also writes header lines containing the artist's name and
* number of works.
*
* If an IOException occurs, the message "IOException occurred" should be
* printed to System.out.
*
* @param writer writer to write this artist's works to
*/
public void saveWorksToFile(Writer writer) {
// write your code here
try {
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(this.name);
buffer.newLine();
buffer.write("works: " + this.works.size());
buffer.close();
}
catch (IOException e) {
System.out.println("IOException occurred");
}
}
}
我遇到了这些错误:
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Vincent van Gogh[newline]works: 0[newline]-----[newline] expected:<...nt van Gogh
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Henry Matisse[newline]works: 1[newline]-----[newline]Woman with a Hat|1905|Oil on canvas expected:<...nry Matisse
=> org.junit.ComparisonFailure: The expected value is: Claude Monet[newline]works: 2[newline]-----[newline]Bridge over a Pond of Water Lilies|1899|Oil on canvas[newline]Impression, Sunrise|1872|Oil on canvas expected:<...laude Monet
我很难换行,我尝试了 \n
和 newLine()
方法,但它不起作用。并且还显示列表中的作品数量应该是正确的。至于循环,我想在这种情况下我应该使用for循环来循环艺术作品。
任何提示/帮助都会很棒,谢谢!
您可以使用 json 格式轻松保存您的数据并像这样组织
public void saveWorksToFile(OutputStreamWriter writer) {
// write your code here
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("ARTIST_NAME",this.name);
jsonObject.put("NUM_WORKS",this.works.size());
for (int i=0;i<works.size();i++) {
jsonObject.put("work_" + i, works.get(i).toString());
// you can save work as a byte array or json string so you could easily import the data back
}
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(jsonObject.toString()+"\n");
buffer.close();
}
catch (IOException | JSONException e) {
System.out.println("IOException occurred");
}
}
public Artist readFromFile(File file){
Artist artist = null;
FileReader fileReader = null;
String line= null;
BufferedReader bufferedReader;
try {
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
line = bufferedReader.readLine();
while (line != null){
line += "\n";
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(line);
String name = jsonObject.get("ARTIST_NAME").toString();
int works_num = Integer.parseInt(jsonObject.get("NUM_WORKS").toString());
// here you can import the works as a string.
artist = new Artist(name);
} catch (JSONException e) {
e.printStackTrace();
}
line = bufferedReader.readLine();
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return artist;
}
我的建议是你分开类,有时很难找出问题。我是这样分开的。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Artist {
private String name; // e.g. "Henri Matisse"
private List<Work> works = new ArrayList<>();
public Artist(String name) {
this.name = name;
}
public void addWork(Work work) {
this.works.add(work);
}
public void saveWork(){
try{
BufferedWriter writer = new BufferedWriter(
new FileWriter("path where want to save"));
writer.write(this.name);
writer.newLine();
writer.write("works: " + this.works.size());
writer.newLine();
this.works.forEach(work -> {
try {
writer.write(work.name);
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
});
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Work {
String name; // e.g. "Mona Lisa"
int yearCreated; // e.g. 1506
String medium; // e.g. "Oil on poplar panel"
public Work(String name, int yearCreated, String medium) {
this.name = name;
this.yearCreated = yearCreated;
this.medium = medium;
}
public String getName() { return name; }
public int getYearCreated() { return yearCreated; }
public String getMedium() { return medium; }
@Override
public String toString() {
return name + "|" + yearCreated + "|" + medium;
}
}
public class Main {
public static void main(String[] args) {
Work work1 = new Work("Fast1",2019,"ss");
Work work2 = new Work("Fast2",2019,"ss");
Artist artist = new Artist("Artist_Tom_Cruise");
artist.addWork(work1);
artist.addWork(work2);
artist.saveWork();
}
}
下面是方法 saveWorksToFile
的代码。这是我更改的问题中唯一的代码部分。 (代码后的注释。)
public void saveWorksToFile(Writer writer) {
try {
writer.write(this.name);
writer.write(System.lineSeparator());
writer.write("works: " + this.works.size());
writer.write(System.lineSeparator());
writer.write("---");
writer.write(System.lineSeparator());
boolean first = true;
for (Work work : works) {
if (first) {
first = false;
}
else {
writer.write(System.lineSeparator());
}
writer.write(work.toString());
}
}
catch (IOException e) {
System.out.println("IOException occurred");
}
}
您不应该将 Writer
参数包装在 BufferedWriter
中。通常,对于任何方法,您通常都不需要强制转换参数。因此,在上面的代码中,我只使用了classWriter
的方法。另请注意,我没有关闭 Writer
因为那应该留给调用方法 saveWorksToFile
.
为了写行分隔符,我调用了classjava.lang.System
的方法lineSeparator
。
为了每行打印一个艺术家的所有作品,我使用了一个循环。
为了确保艺术家作品列表中的最后一个条目没有行分隔符,第一个作品没有行分隔符,后面的每个作品都有前面的行分隔符。
这是我写的一个方法来测试上面的代码。它使用 class java.io.StringWriter
是 Writer
的子 class 因为 class Writer
是抽象的并且没有 public 构造函数。通常,您不能实例化抽象 class。您需要使用具体的 subclass。我使用 StringWriter
以便能够轻松地将其内容打印到屏幕上。如果要写入实际文件,可以使用 class java.io.FileWriter
。
/**
* import java.io.StringWriter
*/
public static void main(String[] args) {
Artist artist = new Artist("Vincent van Gogh");
StringWriter sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
System.out.println();
artist = new Artist("Claude Monet");
Work work = new Work("Bridge over a Pond of Water Lilies", 1899, "Oil on canvas");
artist.addWork(work);
work = new Work("Impression, Sunrise", 1872, "Oil on canvas");
artist.addWork(work);
sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
System.out.println();
artist = new Artist("Henri Matisse");
work = new Work("Woman with a Hat", 1905, "Oil on canvas");
artist.addWork(work);
sw = new StringWriter();
artist.saveWorksToFile(sw);
System.out.print(sw);
}
这是我在 运行 上述 main
方法时得到的输出。
Vincent van Gogh
works: 0
---
Claude Monet
works: 2
---
Bridge over a Pond of Water Lilies|1899|Oil on canvas
Impression, Sunrise|1872|Oil on canvas
Henry Matisse
works: 1
---
Woman with a Hat|1905|Oil on canvas