【问题标题】:Java fileinput (read and write) to a file looping thru each lineJava文件输入(读取和写入)到通过每一行循环的文件
【发布时间】:2014-09-10 00:50:25
【问题描述】:

我有这种访问现有文件的方法,循环遍历每一行并在满足条件时替换(字符串到字符串)某一行:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.InputStreamReader;

private void UpdateConfig() {
    try {
        FileInputStream fstream = new FileInputStream("c:\\user\\config.properties");
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String strLine;
        while ((strLine = br.readLine()) != null) {
            if (strLine.contains("FTPDate=2014/07/01 00:59:00")) {
                System.out.println("FILE " + strLine);
                strLine.replace("FTPDate=2014/07/01 00:59:00", "FTPDate=2014/09/10 00:00:00");
                //strLine.replace("((19|20)\\d\\d/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])", "2014/09/10 00:00:00");
                System.out.println("FILE " + strLine);
            }
        }
        in.close();
    } catch (Exception e) {
    }
}

在 sysout 中,它似乎被替换了:

FILE FTPDateTejas=2014/07/01 00:59:00  
FILE FTPDateTejas=2014/09/10 00:00:00

但是当我检查文件时,日期仍然保持不变。我错过了什么吗?有谁知道我错过了什么?谢谢

【问题讨论】:

  • replace 更改内存中的字符串但不更改磁盘。您需要打开另一个文件进行写入并写出每一行。

标签: java bufferedreader fileinputstream


【解决方案1】:

当你在做的时候:

strLine = br.readLine() 它将下一行从BufferedReader 加载到内存中。这意味着您的数据在磁盘和内存中,并且这两者没有以任何方式相互链接。在对strLine 进行修改时,我相信您的代码中有:

strLine = strLine.replace("FTPDate=2014/07/01 00:59:00", "FTPDate=2014/09/10 00:00:00");

由于replace 不会修改正在调用它的对象的内容,而是返回一个新的String 对象(字符串是不可变的)。那么它会创建一个新对象但不会修改您的磁盘数据(正如我所说,它不再与它链接!)。

您可能会想“好的,那么我如何链接这两个并覆盖文件?”。 Java确实提供了随机文件访问as described in the doc,但你唯一能做的就是modify某个位置的字符,你不能在中间插入东西。所以你需要做的是阅读你的文件的其余部分,进行修改,然后附加文件的其余部分,是的,你需要改变一些东西,以防你替换的新字符串比什么短/长你正在替换。

这就是为什么更简单的解决方案是:

  1. 打开一个要写入的新文件
  2. 逐行写入(替换后的字符串
  3. 删除旧文件并重命名新文件

如果不复制文件,代码将如下所示:

private void UpdateConfig() {
    File fstream = new File("c:\\user\\config.properties");
    File file = new File("c:\\user\\config.properties-new");
    try {
        file.createNewFile();
    } catch (IOException e) {
        // handle
    }
    try (FileReader in = new FileReader(fstream);
         FileWriter fw = new FileWriter(file.getAbsoluteFile())) {

        try (BufferedReader br = new BufferedReader(in);
             BufferedWriter bw = new BufferedWriter(fw)) {
            String strLine;
            while ((strLine = br.readLine()) != null) {
                if (strLine.contains("FTPDate=2014/07/01 00:59:00")) {
                    System.out.println("FILE " + strLine);
                    strLine = strLine.replace("FTPDate=2014/07/01 00:59:00",
                            "FTPDate=2014/09/10 00:00:00");
                    //strLine.replace("((19|20)\\d\\d/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])", "2014/09/10 00:00:00");
                    bw.write(strLine);
                    System.out.println("FILE " + strLine);
                }
            }
        }
        // copy files here
    } catch (IOException e) {
        // handle
    }
}

我在纯文本编辑器中编写时可能存在一些逻辑/句法问题。我稍微修改了代码以使用 Java 7 的 try-with-resources,这是一种关闭资源的比您所做的更干净的方法 - 在您的代码中,当抛出异常时,流可能尚未关闭。

【讨论】:

  • 非常感谢您提供的详细说明以及可以正常工作的示例代码。真的很感激。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 2016-10-02
相关资源
最近更新 更多