Java替换文本文件中的行

7
我从另一个问题中找到了这段代码。
private void updateLine(String toUpdate, String updated) throws IOException {
    BufferedReader file = new BufferedReader(new FileReader(data));
    String line;
    String input = "";

    while ((line = file.readLine()) != null)
        input += line + "\n";

    input = input.replace(toUpdate, updated);

    FileOutputStream os = new FileOutputStream(data);
    os.write(input.getBytes());

    file.close();
    os.close();
}

这是我在替换某些行之前的文件。

example1
example2
example3

但是当我替换一行时,文件现在看起来像这样。
example1example2example3

当文件中有很多行时,这使得阅读该文件变得不可能。

如何编辑上面的代码,使得我的文件看起来像最初那样?


@AstroCB 就是我说的。我的文件看起来很干净,每一行都有,但当我替换其中任意一行时,它会出错并将所有行都放在一起,就像第二个例子所示。 - user3879542
你是在基于Windows的系统上运行吗?那么你必须使用\r\n作为换行符。 - Jens
@Jens 是的,我正在运行Windows。我已经通过使用System.getProperty("line.separator")来修复了这个问题,但我也会记住这一点。谢谢。 - user3879542
1
请在循环内使用读取器、写入器和字符串写入,不要使用“+”来连接字符串。 - Kalpesh Soni
1
@KalpeshSoni 这不是我的代码,我在一个类似的问题中找到了它。我对这些东西不太熟悉,所以我不知道我应该编辑什么。 - user3879542
3个回答

10

使用 System.lineSeparator() 代替 \n

while ((line = file.readLine()) != null)
    input += line + System.lineSeparator();

问题在于Unix系统上的行分隔符是\n,而Windows系统上的行分隔符是\r\n

在Java 7之前的版本中,您需要使用System.getProperty("line.separator")来代替。

如评论所指出的,如果您担心内存使用量,最好不要将整个输出存储在变量中,而是在处理输入的循环中逐行写出它。


我使用Java6,但是使用System.getProperty("line.separator")代替\n完美地工作了。谢谢。 - user3879542
请指出op的代码读取整个文件到一个字符串中是很糟糕的,他应该在while循环中进行写操作。 - Kalpesh Soni
@KalpeshSoni 为什么不自己在问题下添加评论呢?而且,只有当 OP 确实需要担心内存使用情况时,才会变得糟糕,这可能并非总是如此。 - Robby Cornelissen
开发人员永远不需要担心内存使用,他们的系统管理员会处理这个问题。 - Kalpesh Soni
一个赋值语句(例如 line = file.readLine())的输出是什么?我猜想它应该是 line 的内容,但我不知道你可以这样做。你能确认一下吗? - JohnyTex

3

如果您逐行阅读和修改,这样做的好处在于,您不需要将整个文件装入内存。不确定您的情况是否可行,但通常应该采用流式处理。在您的情况下,这还会消除连接字符串的需要,并且您不需要选择行终止符,因为可以使用println()写入每个单独转换的行。它需要写入另一个文件,这通常是一个好习惯,因为它是崩溃安全的。如果重写文件并中途中止,您将丢失数据。

private void updateLine(String toUpdate, String updated) throws IOException {
    BufferedReader file = new BufferedReader(new FileReader(data));
    PrintWriter writer = new PrintWriter(new File(data+".out"), "UTF-8");
    String line;

    while ((line = file.readLine()) != null)
    {
        line = line.replace(toUpdate, updated);
        writer.println(line);
    }
    file.close();
    if (writer.checkError())
        throw new IOException("cannot write");
    writer.close();
}

在这种情况下,它假定您只需要替换完整行而不是多行。我还添加了明确的编码并使用了一个写入器,因为您有一个字符串要输出。

抱歉,我需要修复我的示例,我从原始问题中复制了太多内容:当然应该使用println()。 - eckes
Writer没有名为println的方法,但PrintWriter有。使用此代码会在行PrintWriter writer = new PrintWriter(new FileWriter(data + ".out"));上导致StackOverflowError。 - user3879542
是的,它是PrintWriter。不确定StackOverflow。 - eckes

1
这是因为您使用的是适用于处理二进制数据的OutputStream。尝试使用PrintWriter,并且不要在行末添加任何换行符。示例在此处

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接