java - 为什么 BufferedWriter 不通过打开的 FileChannel 写入文件?
问题描述
下面是我的代码。我能够成功读取文件。但无法使用 BufferedWriter 用替换的内容重新写入它。但可以使用 ByteBuffer 来完成。任何建议,请在哪里出错。
myFile.txt 内容:
Key1-Value1
Key2-Value2
Key3-Value3
Java 代码如下:
String fileAbsolutePath = "C:\\myPath\\myFile.txt";
try {
RandomAccessFile file = new RandomAccessFile(fileAbsolutePath, "rw");
FileChannel fileChannel = file.getChannel();
FileLock lock = fileChannel.lock();
// read from the channel
BufferedReader bufferedReader = new BufferedReader(Channels.newReader(fileChannel, "UTF-8"));
List<String> filteredList = bufferedReader.lines().filter(line -> !line.contains("KEY1-VALUE1")).onClose(() -> {
try {
bufferedReader.close();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}).collect(Collectors.toList());
fileChannel.truncate(0);
BufferedWriter bufferedWriter = new BufferedWriter(Channels.newWriter(fileChannel, "UTF-8"));
for (String string : list) {
bufferedWriter.write(string);//does n't work
bufferedWriter.newLine();
}
lock.release();
file.close();
fileChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
ByteBuffer 部分有效:
ByteBuffer buff = null;
for (int i = 0; i < filteredList.size(); i++) {
buff = ByteBuffer.wrap(filteredList.get(i).concat("\n").getBytes(StandardCharsets.UTF_8));
fileChannel.write(buff);
}
挑战是在BufferedWriter
尝试使用资源后更新代码
try (RandomAccessFile file = new RandomAccessFile(fileAbsolutePath, "rw");
FileChannel fileChannel = file.getChannel();
FileLock lock = fileChannel.lock();
BufferedReader bufferedReader = new BufferedReader(Channels.newReader(fileChannel, "UTF-8"));
BufferedWriter bufferedWriter = new BufferedWriter(Channels.newWriter(fileChannel, "UTF-8"))) {
// read from the channel
List<String> list = bufferedReader.lines().filter(line -> !line.contains("Key1-Value1"))
.collect(Collectors.toList());
fileChannel.truncate(0);
list.forEach(item -> {
try {
bufferedWriter.write(item.concat("\n"));
} catch (IOException e) {
e.printStackTrace();
}
});
bufferedWriter.flush();
}
解决方案
最后不要刷新 BufferedWriter,这意味着它包含您希望写回的部分或全部行。在关闭通道之前添加一个 flush() 以确保缓冲区被写出:
bufferedWriter.flush();
lock.release();
理想情况下,您应该使用try()
资源,以便在适当的时间完全关闭所有文件。
推荐阅读
- plist - 应用程序传输安全异常的 Expo Info.plist 设置
- javascript - 在 dom 中注入 facebook 像素时,jQuery 附加到 vanilla javascript 问题
- mongodb - Mongo 3.6 - 解析对象嵌套列表中的引用对象
- datetime - Power BI 中每个月的周期间列
- java - 单击按钮后没有输出,因为变量不存在?
- ios - 在 iOS 13 上隐藏后退按钮标题
- android - 从 URL 文件将文件上传到 Firebase 存储
- mongodb - 如何从集合中删除文档,如果同一集合中有“n”个文档,其“x”字段值与删除文档相同
- excel - 从另一个工作表中删除文本等于 #N/A 的行
- angularjs - Angular JS 表达式未使用 $http 服务进行评估