在没有任何数据格式的特定行中写入文件

时间:2016-02-20 15:25:24

标签: java

我想要做的是当用户想要编辑他的个人资料然后按下保存更改我想从所有JTextField获取文本并写入该特定行的文件。但经过3天的尝试没有运气。我查看过这里关于阅读和写入文件的所有帖子但没有运气确定所有方法都在下面,我将解释它们

public void save() throws IOException{
    String changes = name.getText() + "" + dob.getText() + "" 
            + "" + address.getText() + "" + town.getText() 
            + "" + number.getText();
    String whichLine = this.staff_no.getText();
    this.name.setEditable(false);
    this.dob.setEditable(false);
    this.address.setEditable(false);
    this.town.setEditable(false);
    this.number.setEditable(false);
    users.saveChanges(changes,whichLine);
}

这里我创建一个字符串,其中包含来自JTextFields的所有文本,将它们设置为false并调用saveChanges方法(假设“替换”此新字符串的方法)

public int getIndex(String staffno){
    for(User user : allUsers){
        if(user.getStaff_No().contains(staffno)){
            this.index = allUsers.indexOf(staffno);
            break;
        }
    }
    return this.index;
}

public void saveChanges(String changes, String whichLine) throws IOException{
    try {
        int count = 0;
        FileWriter writer = new FileWriter("records.txt", true);
        bw = new BufferedWriter(writer);
        while(scan.hasNext()){
            count++;
            if(count == getIndex(whichLine)){
                bw.write(changes);
                bw.newLine();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally{
        if(bw != null){
            bw.close();
            reader.close();
        }
    }
}

现在我在这里获得用户的Staffno并通过我的用户ArrayLists运行它以找到它的索引让我们说它的0.然后我循环通过我之前打开的扫描仪并尝试找到哪条线我可以覆盖那条线。但是我遇到Exception错误,例如Stream closed或NoSuchAnElementException,或者根本没有错误但是没有写我的行或保存它。

这是我打开文件的方法

public void open(){
    try {
        URL path = Users.class.getResource("records.txt");
        File f = new File(path.getFile());
        reader = new BufferedReader(new FileReader(f));
        scan = new Scanner(reader);
    } catch (FileNotFoundException e) {
        System.out.println("File not found");
    }
}

我不关闭扫描仪的原因是因为我会继续使用它来做其他事情

我意识到这是一个特定的场景,而不是一个简单的读/写场景,所以任何帮助都非常感激。

2 个答案:

答案 0 :(得分:2)

您尝试做的事情 - 在文件中间覆盖数据 - 只有在您编写与您要更换的完全相同的字节数时才能完成。也就是说,您不能用不同的行覆盖文件中的一行,除非它们具有完全相同的字节数(根据字符编码不一定是相同的字符数)。

您还要为您正在写入的文件保持扫描程序打开,这只是要求与缓冲相关的问题。

解决问题的绝对最简单的方法是执行coolguy建议并将所有行读入内存,替换或添加行,然后将其全部写回来。

但是,如果您不想或不想将整个文件缓存到内存中,您可以读取文件行以获取行,然后将其写回 - 在您更改相关行后 - 到另一个文件,最后用新文件替换旧文件。

public static void writeChanges(String changes, int whichLine) throws IOException {
    // The files we're working with
    final File database = new File("database.txt");
    final File newDatabase = new File("database.new.txt");
    try(BufferedReader reader = new Bufferedreader(
            new InputStreamReader(new FileInputStream(database)));
            PrintWriter writer = new PrintWriter(newDatabase)) {
        int line = 0;
        String line;
        // Keep reading lines from the source file until we've read them all
        while((line = reader.readLine()) != null) {
            if(line == whichLine) {
                // Write the modified line
                writer.println(changes);
            } else {
                // Write the original line
                writer.println(line);
            }
            line++;
        }
    }
    // Replace the old database with the new
    Files.move(newDatabase.toPath(), database.toPath(), StandardCopyOption.REPLACE_EXISTING);
}

答案 1 :(得分:0)

如果您的文件不大,您可以执行以下操作:

// File file = ...
// int yourLineNumber = ...
List<String> lines = FileUtils.readLines(new FileReader(file));
lines.add(yourLineNumber, "Line to add");
FileUtils.writeLines(file, lines);

我在此代码中使用commons-io库。