我正在逐行读取一个文件,我正在努力使它如果我找到一条符合我特定参数的行(在我的情况下,如果它以某个单词开头),我可以覆盖那条线。
我目前的代码:
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
个对象。
与往常一样,我们非常感谢任何帮助,示例或建议。
谢谢!
答案 0 :(得分:13)
RandomAccessFile似乎很合适。它的javadoc说:
此类的实例支持读取和写入随机访问文件。随机访问文件的行为类似于存储在文件系统中的大量字节。有一种游标或索引到隐含数组中,称为文件指针;输入操作从文件指针开始读取字节,并使文件指针超过读取的字节数。如果以读/写模式创建随机访问文件,则输出操作也可用;输出操作从文件指针开始写入字节,并使文件指针超过写入的字节。写入隐含数组当前末尾的输出操作会导致数组被扩展。文件指针可以由getFilePointer方法读取并由seek方法设置。
也就是说,由于文本文件是顺序文件格式,你不能用不同长度的行替换行而不移动所有后续字符,所以替换行一般会读取和写入整个文件。如果您写入单独的文件,并在完成后重命名输出文件,这可能更容易实现。如果出现问题,这也会更加健壮,因为可以简单地重试初始文件的内容。 RandomAccessFile的唯一优势是您不需要临时输出文件的磁盘空间,并且由于更好的访问位置,可能会从磁盘中获得更好的性能。
答案 1 :(得分:5)
这里最好的选择可能是将文件读入内存(类似于StringBuilder
)并将您想要的输出文件写入StringBuilder
。完成文件阅读后,您需要将StringBuilder
的内容写入文件。
如果文件太大而无法在内存中完成此操作,则您始终可以逐行读取文件内容并将其写入临时文件而不是StringBuilder
。完成后,您可以删除旧文件并移动临时文件。
答案 2 :(得分: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();
}
}