1

Recently I am doing a code review, the code is like this:

File j = new File(aFile);
System.out.println(j.length());
BufferedReader fileReader = new BufferedReader(new FileReader(j));
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(aFile.getPath());
System.out.println(j.length());

I have two questions:

  1. Is j a duplicate of aFile, because I have seen other huge methods for copying files, like here.

  2. The first System.out.println() prints 32 and the second, after creating a file reader, prints 0. So, why are the contents getting deleted? Could someone explain what's happening here?

I put those System.out.println() statements to check if the file is empty or not.

Solution:

After Reading through the answers, I think I found what's wrong with the code. If j is just a reference, then the fileWriter is trying to write into the same file and it is cyclic. Am I right here?

EDIT: This is not a duplicate of suggested question, as the whole confusion was thinking that the j is clone or duplicate of aFile.

Community
  • 1
  • 1
Brainy
  • 29
  • 1
  • 8
  • so what do you want to achieve just to be sure – Maytham Fahmi Apr 13 '17 at 10:18
  • `j` is merely a representation of the actual file's path name: https://docs.oracle.com/javase/7/docs/api/java/io/File.html – domsson Apr 13 '17 at 10:18
  • 1
    what is `aFile` ? There is no File constructor taking a File as parameter. – ToYonos Apr 13 '17 at 10:20
  • Did you check if the file is *actually* empty after running the shown code? What happens if you print out `j.length()` after you `close()` the `BufferedReader` and `FileReader`? My assumption is that either you're not showing us all of the code *or* this might be expected behavior -- maybe `j` can't read the length anymore once the file is open for reading by means of the third line (couldn't find anything on it in the docs yet, though). – domsson Apr 13 '17 at 10:22
  • 1
    I actually ran this code and I'm pretty sure you are not showing us everything. First, I had to add a `try {} catch {}` block. Second, `j.length()` gives me the same output both times. – domsson Apr 13 '17 at 10:32
  • That was the relevant missing line. There is no cyclic anything going on, however, it is just that `FileWriter` will open the file for writing, overriding its previous contents. See my updated answer. – domsson Apr 13 '17 at 12:34
  • Possible duplicate of [Trouble with filewriter overwriting files instead of appending to the end](http://stackoverflow.com/questions/10804286/trouble-with-filewriter-overwriting-files-instead-of-appending-to-the-end) – domsson Apr 13 '17 at 12:34

3 Answers3

2

You're not showing us everything, are you?

The presented code definitely does not change or delete the file, as is already indicated by the names of the classes you are using: BufferedReader, FileReader (note Reader in both).

I thought there might be a slim chance that some operating systems would lock the file once you create the Readers, hence not even allowing a File object to read the length() property anymore. However, I couldn't find that documented or reported anywhere, so I highly doubt it.

I ran the following code, where test is a plain text file containing 0123456789 (length 10):

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

public class StackOverflow {
    public static void main(String[] args) {
        File f = new File("test");
        System.out.println("Length before: " + f.length());
        try {
            BufferedReader fileReader = new BufferedReader(new FileReader(f));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("Length after: " + f.length());
    }
}

Result:

Length before: 10
Length after: 10

Hence, I suspect the issue lies elsewhere.


EDIT:

Now that OP updated the question, we finally have the relevant line:

BufferedWriter fileWriter = new BufferedWriter(new FileWriter(aFile.getPath());

That's why the file is empty and its length 0. FileWriter will open the file for writing and overwrite the existing contents, if any. You can prevent this by passing in a second parameter, making use of another constructor of FileWriter, one that accepts an append flag:

public FileWriter(String fileName, boolean append) throws IOException 
public FileWriter(File file, boolean append) throws IOException

Constructs a FileWriter object given a File object/name. If the second argument is true, then bytes will be written to the end of the file rather than the beginning.

In other words, if you don't want the contents to be overridden, change your above line to:

BufferedWriter fileWriter = new BufferedWriter(new FileWriter(aFile.getPath(), true);
domsson
  • 4,553
  • 2
  • 22
  • 40
0

1) j is not a duplicate, it is a reference to a new file object that wraps the actual file.

2) There is no way this code should delete (or even change) the file. Is there any more code?

Steve Smith
  • 2,244
  • 2
  • 18
  • 22
0

1) Is j a duplicate of aFile, because I have seen other huge methods for copying files, like here and here.

It is a File object constructed from aFile, whatever that may be. This process has nothing whatsoever to do with copying files, whether huge or hugely or otherwise. File just wraps a file name. Not its contents. Your first link has nothing to do with copying files either.

2) The first result prints 32 and the second result after creating a file reader prints 0. So, why are the contents getting deleted?

Obviously this is not the real code. The real test is whether fileReader.read() immediately returns -1.

user207421
  • 305,947
  • 44
  • 307
  • 483