简体   繁体   English

FileInputStream 和 FileOutputStream:读写同一个文件

[英]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.我创建了一个内容为“Hello”的文本文件,我试图从文件中读取这些字符并将其再次写回同一个文件。

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)假设: 1. 文件现在有内容“Hello”(覆盖) 2. 文件现在有内容“HelloHello”(附加) 3. 文件现在有内容无限“Hello”(或抛出异常)

Actual result: Original "Hello" characters gets deleted from the text file, and the file was left empty.实际结果:原来的“Hello”字符从文本文件中删除,文件为空。

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 :我创建了以下方法来将InputStream中的数据“复制”到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.我尝试使用调试器找出问题所在,调试器显示b = in.read()在 while 循环的第一次迭代中被分配了-1 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 statement final FileWriter fos = new FileWriter(testFile);然后我在检查文件内容的同时逐步执行代码,发现“Hello”关键字在语句final 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?我首先认为这是由于InputStreamOutputStream指向同一个文件,所以为了执行安全,文件被 JVM 有点“锁定”?

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);结果是一样的:文件内容在语句FileWriter fos = new FileWriter(testFile);之后被删除了。

My questions is: why the content gets cleaned out by FileWriter ?.我的问题是:为什么内容会被FileWriter清除?。 Is this some behavior related to FileDescriptor?这是与 FileDescriptor 相关的一些行为吗? Is there a way to read and write to the same file?有没有办法读取和写入同一个文件?

Just FYI,仅供参考,

  1. copyStream() method is working fine, I have tested it with other tests. copyStream()方法工作正常,我已经用其他测试对其进行了测试。
  2. It's not about using append() method instead of write()这不是关于使用append()方法而不是write()

The statement FileWriter fos = new FileWriter(testFile);声明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.如果要读取/写入同一文件,请使用 RandomAccessFile:这会调用查找当前 position 并在文件的不同位置执行读取或写入。

https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html

FileWriter actually deletes everything in a file before writing. FileWriter实际上会在写入之前删除文件中的所有内容。 To preserve the text, use要保留文本,请使用

new FileWriter(file, true);

The true parameter is the append parameter of the filewriter.真正的参数是filewriter的append参数。 Otherwise it will just overwrite everything否则它只会覆盖一切

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

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