编写java后从文件打印

时间:2016-05-15 02:18:16

标签: java file-io

我已经尝试找到答案,但我无法通过搜索几个不同的东西。如果我没有正确格式化,请原谅,这是我在这里的第一篇文章。

所以我正在编写一个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个对象,然后将其存储在对象数组中以进行打印和其他操作。

我不认为这应该是问题,因为它使用相同的文件对象。除非我需要在写完后重新创建文件对象?

1 个答案:

答案 0 :(得分:0)

您要打印的数组(从菜单中选择时)是mainClimb[] 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初始化