9

I have a .txt file, which I want to process in Java. I want to delete its last line.

I need ideas on how to achieve this without having to copy the entire content into another file and ignoring the last line. Any suggestions?

weltraumpirat
  • 22,544
  • 5
  • 40
  • 54
Sergiu
  • 2,502
  • 6
  • 35
  • 57

2 Answers2

9

You could find the beginning of the last line by scanning the file and then truncate it using FileChannel.truncate or RandomAccessFile.setLength.

MForster
  • 8,806
  • 5
  • 28
  • 32
  • This does only work on byte basis, wouldn't you have to do the encoding related size calculations by yourself? – Hauke Ingmar Schmidt Feb 05 '12 at 14:02
  • 1
    Obviously, this depends on the encoding. Byte-wise searching for a new-line character (\0x0a) in ASCII or Latin-1 encoding (or other encodings with 1 byte per character) is safe. I believe that doing this for UTF-8 is safe, too, because all multi-byte sequences have the high bit set. It would fail for, e.g., UTF-16. – MForster Feb 05 '12 at 14:16
  • You are right, for typical encodings including UTF-8 this should not be a problem (as long as you can define "line ending", that is ;-)). – Hauke Ingmar Schmidt Feb 05 '12 at 14:23
  • No solution for getting the position of the last new line sign – Waldemar Wosiński Jun 14 '23 at 14:46
1

By using RandomAccessFile you can:

  • find the position of the last new line character. To read the position: getFilePointer(). To truncate the file: setLength(long).
  • optimization: to read only end of the file use method seek(long) to jump ahead. Challenge is to define the jump.

Otherwise read whole file and store only the last position of the "\n". // Unix new line convention

import java.io.*;

public class TruncateFileExample {
    public static void main(String[] args) {
        String filename = "path/to/your/file.txt";

        try (RandomAccessFile raf = new RandomAccessFile(filename, "rw")) {
            long fileLength = raf.length();
            if (fileLength == 0) {
                // File is empty, nothing to delete
                return;
            }

            // Start searching for the last newline character from the end of the file
            long position = fileLength - 1;
            raf.seek(position);

            int lastByte;
            while ((lastByte = raf.read()) != -1) {
                if (lastByte == '\n') {
                    // Found the last newline character
                    break;
                }
                position--;
                raf.seek(position);
            }

            // Truncate the file at the position of the last newline character
            raf.setLength(position);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Waldemar Wosiński
  • 1,490
  • 17
  • 28