繁体   English   中英

如何更新 java 中文本文件的特定部分?

[英]How can I update specific parts of a text file in java?

该程序应该接受有关球员姓名、助攻、所玩比赛、得分等的用户输入,并将其打印在 .txt 文件中。 当 updateData(); 方法被称为我希望能够向用户询问玩家姓名以及他们想要更新的数据,然后我应该能够编辑文本的特定部分。 我怎么能 go 这样做呢?

主Class

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;

public class TextReader {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("/Users/Coding/Desktop/myFile.txt").toAbsolutePath();
        try (Scanner scan = new Scanner(System.in);
             BufferedReader fileReader = new BufferedReader(new FileReader(String.valueOf(path)));
             BufferedWriter fileWriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {

            Reader reader = new Reader(scan, path, fileWriter, fileReader);
            reader.menu();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}



阅读器 Class

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;

public class Reader {

    Path path;
    Scanner scan;
    BufferedWriter fileWriter;
    BufferedReader fileReader;


    Reader(Scanner scan, Path path, BufferedWriter fileWriter, BufferedReader fileReader) {

        this.scan = scan;
        this.path = path;
        this.fileWriter = fileWriter;
        this.fileReader = fileReader;
    }

    public void menu() throws IOException {
        String task;

        do{
            System.out.print("What would you like to do today?: ");
            task = scan.nextLine();
            switch (task) {
                case "1":
                    addData();
                    break;
                case "2":
                    updateData();
                    break;
                case "6":
                    System.out.println("Goodbye!");
                    System.exit(0);
            }
        }while(!task.equals("6"));


    }

    void addData() throws IOException {
        boolean cont;

        DateTimeFormatter log = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        LocalDateTime time = LocalDateTime.now();
        String logTime = log.format(time);

        do try {
            System.out.print("Enter Name of Player: ");
            String playerName = scan.nextLine();

            System.out.print("Enter Number of Games Played: ");
            int gamesPlayed = Integer.parseInt(scan.nextLine());

            System.out.print("Enter Number of Goals Made: ");
            int goals = Integer.parseInt(scan.nextLine());

            System.out.print("Enter Number of Assists Made: ");
            int assists = Integer.parseInt(scan.nextLine());

            System.out.print("Enter Number of Points Scored: ");
            int points = Integer.parseInt(scan.nextLine());

            System.out.print("Enter Number of Saves Made: ");
            int saves = Integer.parseInt(scan.nextLine());

            System.out.print("Enter Number of Shots Made: ");
            int shotsOnGoal = Integer.parseInt(scan.nextLine());

            fileWriter.write(
                    playerName + " " + gamesPlayed + " " + goals + " " +
                            assists + " " + points + " " + saves + " " + shotsOnGoal + " (" + logTime + ") \n");
            cont = false;
        } catch(NumberFormatException e){
            System.out.println("Enter Valid Input");
            cont = true;
        }while(cont);


    }

    void updateData() throws IOException {
        System.out.print("Enter Player Name To Edit Data: ");
        String playerName = scan.nextLine();

        System.out.print("Enter Stat You Want To Change: ");
        String stat = scan.nextLine().toLowerCase().trim();

        if(fileReader.readLine().contains(playerName)){
            String statSearch = fileReader.readLine();
            

            }
        }

    }


}


文本文件格式:

姓名 GP GAPSS%

鲍比 2 3 6 14 7 50

乔治 1 3 14 2 9 23

因此,如果用户想要编辑姓名:George,请输入:Assists,仅编辑 Georges 姓名旁边的值 14

我尝试使用 if 语句来定位文本中的字符串和 append 但我无法弄清楚如何只更改指定的数字而不更改找到的所有数字。 例如:如果在上面的示例中附加了 14,则两者都将被更改而不是一个

如果你被允许参加这个项目(即不是学校作业),我建议使用 JSON、YAML 或 XML。 推荐使用这些类型的文件的 Java 库太多,但您可以搜索“Java JSON 库”例如。

首先,需要解决一些问题...

Scanner scan = new Scanner(System.in); 在资源尝试中。 它将自动关闭System.in ,并且在您的Reader class 中使用后将无法使用。 相反,只需这样做:

Scanner scan = new Scanner(System.in);
Reader reader = new Reader(scan, path, fileWriter, fileReader);

或者,更好的是,不要将它传递给构造函数,而只需在构造函数中将scan设置为this.scan = new Scanner(System.in);

接下来,对于fileReader ,您可以像对fileWriter一样初始化它:

BufferedReader fileReader = Files.newBufferedReader(path, StandardCharsets.UTF_8);

接下来,这一行:

BufferedWriter fileWriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8)

每次运行此程序时,此行都会将文件覆盖为空,这可能不是您想要的。 您可以添加StandardOpenOption.APPEND ,但这意味着您只会写入文件末尾。

更新数据时,您还会遇到需要“下推”其后的所有数据的问题。 例如:

Bobby 1 2 3 4 5
Fred 1 2 3 4 5

如果您将名称Bobby更改为更长的名称,例如Mr. President ,那么它将覆盖其后的数据。

虽然有不同的选项,但最好和最简单的方法是读取整个文件并将每一位数据存储在 class(名称、分数等)中,然后关闭 fileReader。

然后,当用户更新某些数据时,更改 class 中的数据(实例变量),然后将所有数据写入文件。

这是一些伪代码:

class MyProg {
  // This could be a Map/HashMap instead.
  // See updateData().
  public List<Player> players = new ArrayList<>();

  public void readData(String filename) throws IOException {
    Path path = Paths.get(filename);
    
    try(BufferedReader fileReader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
      // Read each Player (using specific format)
      // and store in this.players
    }
  }

  public void writeData(String filename) throws IOException {
    Path path = Paths.get(filename);

    try(BufferedWriter fileWriter = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {
      // Write each Player from this.players in specific format
    }
  }

  public void updateData() {
    // 1. Find user-requested Player from this.players
    // 2. Update that specific Player class
    // 3. Call writeData()
    
    // If you are familiar with Maps, then it would be faster
    // to use a Map/HashMap with the key being the player's name.
  }
}

class Player {
  public String name;
  public int games;
  public int goals;
  //...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM