java - FileInputStream and FileOutputStream: Read and write to the same file
问题描述
I created a text file with the content "Hello" and I was trying to read these characters from the file and write it back to the same file again.
Assumptions: 1. the file now has the content "Hello" (Overwritten) 2. the file now has the content "HelloHello" (Appended) 3. the file now has the content infinite "Hello" (or an exception gets thrown)
Actual result: Original "Hello" characters gets deleted from the text file, and the file was left empty.
Actual test
@Test
public void testCopyStream() throws IOException {
File workingDir = new File(System.getProperty("user.dir"));
File testFile = new File(workingDir, "/test.txt");
FileReader fin = new FileReader(testFile);
FileWriter fos = new FileWriter(testFile);
copyStream(fin, fos);
fin.close();
fos.close();
}
I have created the following method for "copying" the data in the InputStream
to the OutputStream
:
private void copyStream(Reader in, Writer out) throws IOException {
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
}
I tried using debugger to find out the problem, and the debugger shows b = in.read()
was assigned -1
at the first iteration of the while loop. Then I executed the code step by step while inspecting the file's content and found that "Hello" keyword got deleted from the file right after statementfinal FileWriter fos = new FileWriter(testFile);
gets executed.
I first thought this was due to the InputStream
and OutputStream
were pointed to the same file so the file gets sort of "locked" by JVM for execution safety?
So I tried swapping those two lines:
FileWriter fos = new FileWriter(testFile);
FileReader fin = new FileReader(testFile);
And the result turned out the same: the file content got eliminated right after the statement FileWriter fos = new FileWriter(testFile);
My questions is: why the content gets cleaned out by FileWriter
?. Is this some behavior related to FileDescriptor? Is there a way to read and write to the same file?
Just FYI,
copyStream()
method is working fine, I have tested it with other tests.- It's not about using
append()
method instead ofwrite()
解决方案
The statement FileWriter fos = new FileWriter(testFile);
truncates the existing file.
It does not make sense for you to use streaming access to read and write the same file, as this won't give reliable results. Use RandomAccessFile if you want to read / write the same file: this has calls to seek current position and perform read or writes at different positions of a file.
https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html
推荐阅读
- regex - 有没有像我需要的那样匹配的正则表达式搜索?
- python - 熊猫:将字典字典转换为熊猫数据框
- javascript - 如何设置日期条件Javascript
- node.js - Node-JS 使用 FFMPEG 将 mp4 转换为 m3u8:无法为 'v:1,a:1"' 找到合适的输出格式
- php - 将 PHP 变量从文本字段传递到 bash 脚本并执行
- django - 如何向 Django 测试请求添加标头?
- php - 删除姓氏,但使用 XSLT 保持首字母
- javascript - Javascript按钮功能卡住
- swagger - Swagger docs - 单个 http 响应的多个错误代码
- python - 在我的 python 应用程序中使用 Tkinter 单选按钮小部件作为 GUI