在Java中同时读写文件

10

我正在逐行读取文件,并尝试使得当我到达符合我特定参数的行时(在我的情况下如果它以某个特定单词开头),我可以覆盖那一行。

当前代码:

try {
    FileInputStream fis = new FileInputStream(myFile);
    DataInputStream in = new DataInputStream(fis);
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    String line;

    while ((line = br.readLine()) != null) {
        System.out.println(line);
            if (line.startsWith("word")) {
                // replace line code here
            }
    }
} catch (Exception ex) {
    ex.printStackTrace();
}

...其中myFile是一个File对象。

和往常一样,任何帮助、示例或建议都将不胜感激。

谢谢!


1
为什么不一次性读取整个文件,关闭它,再打开它进行写入,并在执行转换后写出每一行呢? - Patashu
1
@Patashu 如果它是一个大文件呢?那么,我的建议方法会更有效。 - iphonedev7
请勿使用DataInputStream读取文本 http://vanillajava.blogspot.co.uk/2012/08/java-memes-which-refuse-to-die.html - Peter Lawrey
3个回答

17

RandomAccessFile似乎很合适。其javadoc说:

该类的实例同时支持读写随机访问文件。 随机访问文件的行为类似于存储在文件系统中的大型字节数组。有一种光标或索引进入隐含数组,称为文件指针;输入操作从文件指针开始读取字节,并将文件指针推过读取的字节。如果以读/写模式创建随机访问文件,则还可以使用输出操作;输出操作从文件指针开始写入字节,并将文件指针推过写入的字节。越过隐含数组当前结尾的输出操作会导致数组被扩展。getFilePointer方法可读取文件指针,而seek方法可设置文件指针。

话虽如此,由于文本文件是顺序文件格式,因此无法用不同长度的行替换行而不移动所有后续字符,因此替换行通常意味着读取和写入整个文件。如果写入单独的文件,然后在完成后重命名输出文件,这可能更容易实现。如果发生问题,这也更加健壮,因为可以简单地使用初始文件的内容重试。 RandomAccessFile的唯一优点是您不需要临时输出文件的磁盘空间,并且由于访问局部性更好,可能会获得略高的磁盘性能。


6
你最好的选择可能是将文件读入内存(类似于StringBuilder),并将你想要输出的文件内容写入StringBuilder中。在完全读取文件后,你需要将StringBuilder的内容写入文件。
如果文件太大而无法在内存中完成此操作,则可以逐行读取文件内容并将其写入临时文件而不是StringBuilder。完成后,你可以删除旧文件并将临时文件移动到相同的位置。

好主意...我会试一下。 - iphonedev7

0

一个老问题,最近我在处理它。分享一下我的经验。

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public static void updateFile(Path file) {

    // Get all the lines
    try (Stream<String> stream = Files.lines(file,StandardCharsets.UTF_8)) {
        // Do the replace operation
        List<String> list = stream.map(line -> line.replaceAll("test", "new")).collect(Collectors.toList());
        // Write the content back
        Files.write(file, list, StandardCharsets.UTF_8);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

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