简体   繁体   English

在java中同时读取和写入文件

[英]Read and Writing to a file simultaneously in java

I'm reading a file line by line, and I am trying to make it so that if I get to a line that fits my specific parameters (in my case if it begins with a certain word), that I can overwrite that line.我正在逐行读取文件,并且我正在尝试使其成为适合我的特定参数的行(在我的情况下,如果它以某个单词开头),我可以覆盖该行。

My current code:我目前的代码:

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();
}

...where myFile is a File object. ...其中myFile是一个File对象。

As always, any help, examples, or suggestions are much appreciated.与往常一样,非常感谢任何帮助、示例或建议。

Thanks!谢谢!

RandomAccessFile seems a good fit. RandomAccessFile似乎很合适。 Its javadoc says:它的 javadoc 说:

Instances of this class support both reading and writing to a random access file.此类的实例支持读取和写入随机访问文件。 A random access file behaves like a large array of bytes stored in the file system.随机访问文件的行为类似于存储在文件系统中的大量字节。 There is a kind of cursor, or index into the implied array, called the file pointer;有一种游标,或隐含数组的索引,称为文件指针; input operations read bytes starting at the file pointer and advance the file pointer past the bytes read.输入操作从文件指针开始读取字节,并将文件指针前进到读取的字节之后。 If the random access file is created in read/write mode, then output operations are also available;如果随机存取文件是以读/写方式创建的,那么也可以进行输出操作; output operations write bytes starting at the file pointer and advance the file pointer past the bytes written.输出操作从文件指针开始写入字节,并将文件指针前进到写入的字节之后。 Output operations that write past the current end of the implied array cause the array to be extended.写入超过隐含数组当前末尾的输出操作会导致数组被扩展。 The file pointer can be read by the getFilePointer method and set by the seek method.文件指针可以通过 getFilePointer 方法读取并通过 seek 方法设置。

That said, since text files are a sequential file format, you can not replace a line with a line of a different length without moving all subsequent characters around, so to replace lines will in general amount to reading and writing the entire file.也就是说,由于文本文件是一种顺序文件格式,您不能在不移动所有后续字符的情况下用不同长度的行替换一行,因此替换行通常相当于读取和写入整个文件。 This may be easier to accomplish if you write to a separate file, and rename the output file once you are done.如果您写入单独的文件并在完成后重命名输出文件,这可能更容易完成。 This is also more robust in case if something goes wrong, as one can simply retry with the contents of the initial file.如果出现问题,这也更加健壮,因为您可以简单地重试初始文件的内容。 The only advantage of RandomAccessFile is that you do not need the disk space for the temporary output file, and may get slight better performance out of the disk due to better access locality. RandomAccessFile 的唯一优点是您不需要用于临时输出文件的磁盘空间,并且由于更好的访问局部性,可能会从磁盘中获得稍微更好的性能。

Your best bet here is likely going to be reading in the file into memory (Something like a StringBuilder ) and writing what you want your output file to look like into the StringBuilder .您最好的选择可能是将文件读入内存(类似于StringBuilder )并将您希望输出文件的外观写入StringBuilder After you're done reading in the file completely, you'll then want to write the contents of the StringBuilder to the file.完全读入文件后,您需要将StringBuilder的内容写入文件。

If the file is too large to accomplish this in memory you can always read in the contents of the file line by line and write them to a temporary file instead of a StringBuilder .如果文件太大而无法在内存中完成此操作,您始终可以逐行读取文件的内容并将它们写入临时文件而不是StringBuilder After that is done you can delete the old file and move the temporary one in its place.完成后,您可以删除旧文件并将临时文件移到其位置。

An old question, recently worked on this.一个老问题,最近在解决这个问题。 Sharing the experience分享经验

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM