当前位置: 首页 > 知识库问答 >
问题:

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

史意致
2023-03-14

我有一个格式像这个 id,textcsv 文件。下面是一个示例:

helloText,How are you
goodbyeMessage,Some new text for a change
errorMessage,Oops something went wrong

现在,假设我想编辑< code>goodbyeMessage的文本部分,即< code >一些新的更改文本,以< code>See you later

生成的<code>csv</code>应该如下所示:

helloText,How are you
goodbyeMessage,See you later
errorMessage,Oops something went wrong

我有可以写入文件的代码,但是当代码完成执行时,这是生成的csv文件:

helloText,How are you
goodbyeMessage,Some new text for a change
errorMessage,Oops something went wronggoodbyeMessage,See you later

我知道这种情况正在发生,因为我将文件编写器的追加值设置为 true。如果我不这样做,一切都会被擦拭。

我尝试过使用<code>FileWriter。newLine()使它看起来更好,但这不是我想要实现的。我仍然希望文件中的行数相同。我的应用程序.java

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

属性编写器.java

/**
 * Updates the text of a given element in the properties file.
 * 
 * @param id The id of the element
 * @param newText The text that will replace the original text.
 * 
 * @throws IOException If I/O error occurs
 */
public void updateElementText(String id, String newText) throws IOException {
    Assertions.checkNotNull(id, "Id must not be null.");
    Assertions.checkNotNull(id, "Id must not be an empty string.");
    File file = new File(pathName);
    BufferedReader br = new BufferedReader(new FileReader(file));
    BufferedWriter wr = new BufferedWriter(new FileWriter(file, true));
    try {
        String line;

        while((line = br.readLine()) != null) {
            if(line.contains(id)) {
                //returns true
                System.out.println("Is line there: " + line.contains(id));

                //returns helloText
                System.out.println("ID: " + extractId(line));

                //returns How are you
                System.out.println("TEXT: " + extractText(line));

                //returns Some new text for a change
                System.out.println("NEW_TEXT: " + newText);

                // This is where I am trying to replace the old text 
                // with new text that came from the main method.
                line = line.replaceAll(extractText(line), newText); 
                //wr.newLine();
                wr.write(line);             
            }
        }
    } catch(IOException e) {
        e.printStackTrace();
    } finally {
        wr.close();
    }
}

/**
 * Gets the id part of a line that is stored in the 
 * properties file.
 * 
 * @param element The element the id is got from.
 * @return String representation of the id.
 */
private static String extractId(String line) {
    final int commaOccurence = getFirstCommaOccurrence(line);
    return line.substring(0, commaOccurence);
}

/**
 * Gets the text part of a line that is stored in the 
 * properties file.
 * 
 * @param element The element the text is got from.
 * @return String representation of the text.
 */
private static String extractText(String line) {
    final int commaOccurence = getFirstCommaOccurrence(line);
    return line.substring(commaOccurence + 1, line.length());
}

/**
 * Gets the first occurrence of a comma in any given line of a text file.
 * @param element
 * @return
 */
private static int getFirstCommaOccurrence(String line) {
    return line.indexOf(",");
}

共有2个答案

谷梁建中
2023-03-14

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

Files类提供了一种方便的方法来将整个文件读入List

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

  • getFilePointer() - 返回当前文件偏移量
  • 搜索(长 POS) - 将文件偏移量提前 POS
  • write(byte[] b) - 将 b 写入当前文件位置

希望这有所帮助

景岳
2023-03-14

你刚刚说了。不要将FileWriter设置为true(因为它只会附加新的内容)。您需要读取整个文件,保存所有行(例如,在<code>列表中

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

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

其次,始终写入文件,因为其他行会丢失:

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

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

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

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

 类似资料:
  • 我仍然是python的新手,我已经尝试过这种方式覆盖txt文件上的一行 ''' 答案 =输入(“俄/秒/升/米:”) ''' 它会替换txt文件上的所有文本行,无论我想做什么,当我选择R时,它会写入txt文件的第一行,当我选择S时,它会写入txt文件的第三行 我现在已经尝试过了 ''' ''' 有人能告诉我正确的方向吗

  • 我正在Java写一个程序来更新文本文档上的数据。更新由按钮(JButton)触发。 特别是,我需要区分文档中的3行: 第一个描述了一个名为“total”的浮点值 第二个描述了一个名为“fail”的浮点值 第三个描述了一个称为“rate”的双值 在程序执行期间,我希望读取文档的3行并将其分配给变量;按下按钮后,相应的变量必须覆盖文档中的值。 为了实现这一点,我的理由如下: 我声明了3个私有变量(总数

  • 问题内容: 我编写的代码应该覆盖所选文本文件的内容,但是会附加它。我到底在做什么错? 编辑 我尝试制作一个新的temp.txt文件并将新内容写入其中,删除此文本文件并将temp.txt重命名为该文件。事实是,删除总是不成功的。我认为我不必为此更改用户权限吗? 另外,程序的一部分列出了该目录中的所有文件,因此我猜它们正在被程序使用,因此无法删除。但是为什么不覆盖呢? 解决了 我最大的“ D’oh”时

  • 问题内容: 使用node.js覆盖大型(2MB +)文本文件中的行的最佳方法是什么? 我目前的方法涉及 将整个文件复制到缓冲区中。 通过换行符()将缓冲区拆分为一个数组。 通过使用缓冲区索引覆盖行。 与连接后,用缓冲区覆盖文件。 问题答案: 首先,您需要搜索行的起点和终点。接下来,您需要使用一个函数来替换该行。我使用我的一个库来解决第一部分的问题:Node- BufferedReader 。

  • 问题内容: 给定一个大文件(数百MB),我将如何使用Python快速读取文件中特定起始索引和结束索引之间的内容? 本质上,我正在寻找一种更有效的方法: 问题答案: 您可以将文件放入文件,然后从那里读取一定数量。Seek允许您获取文件中的特定偏移量,然后可以将读取限制为该范围内的字节数。 那只会读取您要查找的数据。

  • 问题内容: 覆盖文件中特定行的最佳方法是什么?我基本上想在文件中搜索字符串’@parsethis’,然后用其他东西覆盖该行的其余部分。 问题答案: 如果文件不是太大,最好的方法可能是使用file()将文件读入行数组,在行数组中搜索您的字符串并编辑该行,然后将implode()返回一起将其fwrite()返回文件。