javafileexceptionnewlinecontent-length

.txt Reader/Writer displaying wrong size in bytes of txt (and more)


I wanted to make a program in Java that checks if src exists (if not to throw an FileNoot)
and to copy the contents of src.txt to des.txt
and to print the sizes of two files at the opening and the closing

The output is:

src.txt is in current directory
Before opening files:Size of src.txt:43 Bytes   Size of des.txt:0 Bytes
After closing files:Size of src.txt:43 Bytes    Size of des.txt:0 Bytes

After src.txt writes its contents in des.txt , des should be 43 bytes

First, I would like to ask if I can omit File declaration by writing

PrintWriter outStream = new PrintWriter(new FileWriter("des.txt")); 

Secondly,I would like to ask how to adapt the following switch case (system indepent newline)
In order to add a newline after the one read.


Thirdly,I would like to ask the importance of try/catch block while closing File
Terribly sorry for this type of question but In C there was no error handling(I think) close() was certain to work


I am sorry for these types of questions but I am a beginner in java

import java.io.*;
public class Main 
{
    public static void main() throws FileNotFoundException
    {

    File src = new File("src.txt");
    if(src.exists())
        System.out.println("src.txt is in current directory");
    else throw new FileNotFoundException("src.txt is not in current directory");
    
    BufferedReader inStream = null;
    PrintWriter outStream = null;
    try {
        File des = new File("des.txt");
        inStream = new BufferedReader(new FileReader(src));
        outStream = new PrintWriter(new FileWriter(des));
        
        System.out.print("Before opening files:Size of src.txt:"+src.length()+" Bytes\t");
        System.out.println("Size of des.txt:"+des.length()+" Bytes");
        int c;
        while((c = inStream.read()) != -1) {
            switch(c){
                case ' ': outStream.write('@');
                          break;
                case '\r':
                case '\n':outStream.write('\n');
                          outStream.write('\n');
                          break;
                default:outStream.write(c);
            }
        }
        System.out.print("After closing files:Size of src.txt:"+src.length()+" Bytes\t");
        System.out.println("Size of des.txt:"+des.length()+" Bytes");
        
    } catch(IOException io) {
        System.out.println("Read/Write Error:"+io.toString());
    } finally {
        try {
                if (inStream != null) {
                    inStream.close();
                }
                 
                if (outStream != null) {
                    outStream.close();
                }
        } catch (IOException io) {
            System.out.println("Error while closing Files:"+io.toString());
          } 
        }
    }
}

Solution

  • You have 3 questions inside your main question

    1. The problem of the file sizes not being correct after you are done is caused by buffering of the file contents, by default it buffers some data to prevent short writes to the hard disk, causing lowered performance, check the size of you file after you closed the file so you see the correct size with the .length() call.

    2. You can use

      PrintWriter outStream = new PrintWriter(new FileWriter("des.txt")); 
      

      inside your code, since FileWriter accepts a String argument at its constructor.

    3. It is recommend practice to close file handler/streams since they are not automatically closed at the time you are done with them, since the garbage collector don't run whole the time, but only at the times there is need for it, this can cause problems with undeletable files since the are still in use by a stream you cannot reach, but is still loaded inside the memory, this can also some problems with the fact that some streams are delayed writing using buffers, and if they are not closed, it causes problems that identify itself as your first problem.