在Java中,如何覆盖文件中某一行的特定部分?

时间:2016-07-25 20:23:44

标签: java file file-writing random-access

我有一个格式为csv的{​​{1}}文件。这是一个例子:

id,text

现在让我们假设我想编辑helloText,How are you goodbyeMessage,Some new text for a change errorMessage,Oops something went wrong goodbyeMessage的文字部分,Some new text for change

结果See you later应如下所示:

csv

我有可以写入文件的代码但是当代码完成执行时,这是生成的helloText,How are you goodbyeMessage,See you later errorMessage,Oops something went wrong 文件:

csv

我知道这是因为我将FileWriter的helloText,How are you goodbyeMessage,Some new text for a change errorMessage,Oops something went wronggoodbyeMessage,See you later 值设置为append。如果我没有一切都被抹去。

我尝试使用true让它看起来更好,但这不是我想要实现的目标。我仍然希望文件中的行数相同。 MyApp.java

FileWriter.newLine()

PropsWriter.java

public static void main(String[] args) throws FileNotFoundException, IOException {
    PropsWriter pw = new PropsWriter("test_props.txt");
    pw.updateElementText("goodbyeMessage", "See you later");
}

2 个答案:

答案 0 :(得分:0)

不幸的是,除了将所有文件数据加载到某个可变对象中,然后将其全部写回文件之外,我还没有办法(我知道)这样做。

Files类提供了将整个文件读入List

的便捷方法

正如@Zabuza在评论中提到的,Java提供了一个名为RandomAccessFile的类,它可以导航到文件中的特定位置并覆盖字节。 您可能感兴趣的方法是:

希望这有帮助

答案 1 :(得分:0)

你刚才这么说。不要将FileWriter设置为true(因为它只会追加新内容)。您需要读取整个文件,保存所有行(例如在List<String>中)。然后你操纵数据。然后你重写整个文本(例如使用所说的List<String>)。

在上面的代码中,首先true替换为false

BufferedWriter wr = new BufferedWriter(new FileWriter(file, false));

第二次,总是写入文件,因为其他行会丢失:

if(line.contains(id)) {
    ...
    line = line.replaceAll(extractText(line), newText); 
}
wr.write(line);

但是,如果您有一个非常大的文件并且不想重写所有行,那么您可以选择更低级别的FileWriter,例如{{ 1}}。此概念允许您在给定位置开始文件操作,而无需重写此位置之前的所有内容。您可以搜索该行(或跳转,如果您知道在哪里),进行更改。但是你需要重写之后更改的所有内容。这是一个用法示例:RandomAccessFile example

没有更好的解决方案,因为这取决于平台。更具体地说,它取决于使用的文件系统,例如RandomAccessFileNTFS等。
通常,它们通过将文件拆分为多个包来存储文件。然后将包保存在整个硬盘驱动器上,它将它们放在最适合的位置。文件系统在FAT32中保存指向文件的每个启动包的指针。然后,每个包都会保存指向下一个包的指针,依此类推,直到达到master table

你知道,在不改变之前的所有内容的情况下,很容易改变中间的东西。但是您可能需要更改后面的内容,因为您无法控制EOF如何将新数据拆分为包。如果你去非常低级,你可以控制单个包并注入数据,而不会改变所有内容。但我不认为你想这样做:)