我已经尝试找到答案,但我无法通过搜索几个不同的东西。如果我没有正确格式化,请原谅,这是我在这里的第一篇文章。
所以我正在编写一个java程序,它基本上会记录用户在不同路线和难度下的攀岩历史。
我遇到写入文本文件的问题(我还是FileIO
的新手),在写入文件后,写入的新信息在我退出之后才会打印出来程序并重新启动它。这是程序,有问题的方法是writer()
:
public class Climb {
private String name;
private char type;
private double rating;
private char subRating;
private String loc;
private int tries;
public Climb(){}
public Climb(String name, char type, double rating, char subRating, String loc, int tries) {
this.name = name;
this.type = type;
this.rating = rating;
this.subRating = subRating;
this.loc = loc;
this.tries = tries;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getType() {
return type;
}
public void setType(char type) {
this.type = type;
}
public double getRating() {
return rating;
}
public void setRating(double rating) {
this.rating = rating;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public int getTries() {
return tries;
}
public void setTries(int tries) {
this.tries = tries;
}
public char getSubRating() {
return subRating;
}
public void setSubRating(char subRating) {
this.subRating = subRating;
}
public static String header (){
return String.format("%-10s %-10s %-10s %-10s %-10s","Name","Type","Rating","Location","Attempts");
}
@Override
public String toString() {
String tempRating = Double.toString(rating) + subRating;
return String.format("%-10s %-10s %-10.5s %-10s %-10s %n", name, type, tempRating, loc, tries);
}
}
public class ClimbTracker {
/*
* prints a formatted output of an array of Climb objects
*/
public static void printRecord (Climb[] c) {
try {
System.out.println(Climb.header());
for (int i = 0; i < c.length; i++){
System.out.print(c[i].toString());
}
}
catch (NullPointerException ex) {
System.out.println("Error: " + ex.getMessage());
}
}
/*
* Creates a new array of Climb objects from a file and return the array.
* Number of objects in file doesn't need to be known
*/
public static Climb[] objFromFile (File fn){
try {
Scanner file = new Scanner(fn);
ArrayList<Climb> climbsArray = new ArrayList<>();
Climb[] climbObjArray;
while (file.hasNext()) {
// name, type, rating, subRating, location, tries
String name = file.next();
char type = file.next().charAt(0);
String temp = file.next();
char subRating;
double rating;
/*
* This if block is to deal with the problem that climbing
* ratings are often something like "5.12a", so it splits it
* into a double and a char as rating and subRating respectively
*/
if (temp.length() > 3){
subRating = temp.charAt((temp.length() -1));
temp = temp.substring(0, temp.length() -1);
rating = Double.parseDouble(temp);
} else {
rating = Double.parseDouble(temp);
subRating = ' ';
}
String loc = file.next();
int tries = file.nextInt();
Climb climb1 = new Climb(name,type,rating,subRating,loc,tries);
climbsArray.add(climb1);
}
climbObjArray = new Climb[climbsArray.size()];
for (int i = 0; i < climbsArray.size(); i++) {
climbObjArray[i] = climbsArray.get(i);
}
return climbObjArray;
}
catch (FileNotFoundException ex){
System.out.println("Error " + ex.getMessage());
}
return null;
}
/*
* Will write new climbs to the file
*/
public static void writer (File fn, Scanner input){
try {
FileOutputStream fn_stream = new FileOutputStream(fn,true);
PrintWriter out = new PrintWriter(fn_stream);
System.out.print("Name of route: ");
out.print(input.next() + " ");
System.out.print("(B)ouldering or (t)oprope: ");
out.print(input.next().charAt(0) + " ");
System.out.print("Rating: ");
out.print(input.next() + " ");
System.out.print("Location of route: ");
out.print(input.next() + " ");
System.out.print("Number of attempts: ");
out.print(input.next() + "\n");
out.flush();
fn_stream.flush();
out.close();
fn_stream.close();
} catch (FileNotFoundException ex) {
System.out.println("Error: " + ex.getMessage());
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
} finally {
objFromFile(fn);
}
}
public static void main(String[] args) {
File fn = new File("climbs.txt");
Scanner input = new Scanner(System.in);
Climb[] c = objFromFile(fn);
while (true) {
System.out.println("What would you like to do?");
System.out.println("(P)rint recent climbs");
System.out.println("(W)rite others");
System.out.println("(E)xit");
char option = input.next().charAt(0);
switch (option){
case 'p':
printRecord(c);
break;
case 'w':
writer(fn, input);
break;
case 'e':
System.exit(0);
break;
default:
System.out.println("That isn't an option");
}
}
}
}
finally块中的方法读取文件并创建ArrayList
个对象,然后将其存储在对象数组中以进行打印和其他操作。
我不认为这应该是问题,因为它使用相同的文件对象。除非我需要在写完后重新创建文件对象?
答案 0 :(得分:0)
您要打印的数组(从菜单中选择时)是main
中Climb[] c
的数组,而writer()
被调用后加载/刷新的数组是另一个它位于objFromFile()
中,因此您将加载到一个数组中,并打印另一个Climb[] climbObjArray
。
所以我建议您删除finally
块,并在匹配器objFromFile()
的情况下调用main
中的write
,以便main
中的数组为更新,因此当用户选择功能print
1-从writer()
finally {
objFromFile(fn);
}
2-更新case 'w'
如下:
case 'w':
writer(fn, input);
c = objFromFile(fn); // <--- add this
break;
现在匹配case 'p'
时,调用printRecord(c);
会传递更新的c
。
PS:将ArrayList
转换为数组的更好方法是使用toArray()
代替for循环
climbObjArray = climbsArray.toArray(new Climb[climbsArray.size()]);
用上面的行
替换for循环和数组climbObjArray
初始化