Search code examples
javafiletruncater.java-file

How to delete the file contents (not file, need same inode) in Java and then truncate the file to a specific size (say 38 bytes)


I want to achieve the following in Java realm:

  • Open a non-zero sized file.
  • Delete all its contents.
  • Truncate the same file to a given size (Say 38 bytes ....)

  • Somehow, if I delete the contents (works), even if I issue truncate after that, its not honored and file size stays 0.

        String fileName = "/home/me/dummy/a.1";
        try {
             Long size = 0L;
    
             // file exists already
             RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
             // set the file pointer at 0 position
             raf.seek(0);
             // print current length
             size = raf.length();
             System.out.println("Before deleting -  fileSize = " + size);
    
             // set the file length to 0
             raf.setLength(0);
             // print the new length
             System.out.println("After deleting - filesize = " + raf.length());
             raf.close();
    
    
            // truncating file to Size = 38 bytes
            FileChannel outChan = new FileOutputStream(fileName, true).getChannel();
            System.out.println("Before Truncating - File size = "+outChan.size());
            outChan.truncate(38);
            System.out.println("Aftre truncating  - File size = "+outChan.size());
            outChan.close();
    
        } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        } 
    

My O/Ps :

Before deleting - fileSize = 21

After deleting - filesize = 0

Before Truncating - File size = 0

Aftre truncating - File size = 0



I have tried multiple other options like :

  1. Truncating the file to 0 and then to say 38 bytes (non-zero value that i want)

            // truncating file to Size = 0 bytes and then to 38 bytes
            FileChannel outChan = new FileOutputStream(fileName, true).getChannel();
            System.out.println("Before Truncating - File size = "+outChan.size());
            outChan.truncate(0);                
            outChan.truncate(38);
            System.out.println("Aftre truncating  - File size = "+outChan.size());
            outChan.close();
    

Doesn't work. File Size stays 0. Only 1st truncate is honored.



2. Truncate the file to 0, close the channel, open the channel again and truncate to 38 bytes.

            FileChannel outChan = new FileOutputStream(fileName, true).getChannel();
            System.out.println("Before Truncating - File size = "+outChan.size());
            outChan.truncate(0);    
            outChan.close();
             FileChannel outChan1 = new FileOutputStream(fileName, true).getChannel();          
            outChan1.truncate(38);
            System.out.println("Aftre truncating  - File size = "+outChan1.size());
            outChan.close();

Doesn't work. File Size stays 0. Only 1st truncate is honored.



Your inputs on how can I delete the file contents and truncate it to a non-zero size. It would b great if i can do it in only one open unlike opening it as (RandomAccessFile and then as FileChannel).

Thanks.


Solution

  • Quoting from FileChannel.truncate javadocs:

    If the given size is greater than or equal to the file's current size then the file is not modified.

    Since you emptied the file before truncating, its size will be 0. 38 > 0, so issuing a .trucate(38) will result in a no-op.

    Either you truncate to 38 bytes without trucating to 0 first, or you truncate to 0 and write 38 bytes to it (e.g. 38 zeroes).