tail-n

 avatar
user_0606344
java
a month ago
2.9 kB
7
Indexable
Never
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.Deque;

public class TailNWithByteBuffer {

    private static final int BUFFER_SIZE = 4096;  // Size of the ByteBuffer

    public static Deque<String> tail(String fileName, int n) throws IOException {
        Deque<String> result = new ArrayDeque<>(n);  // Efficient deque to store last n lines
        try (RandomAccessFile file = new RandomAccessFile(fileName, "r");
             FileChannel channel = file.getChannel()) {
            
            long fileSize = channel.size();
            ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
            long pos = fileSize;
            int lineCount = 0;
            StringBuilder currentLine = new StringBuilder();

            while (pos > 0) {
                // Calculate the position and the amount of data to read
                long readStart = Math.max(0, pos - BUFFER_SIZE);
                int readSize = (int) (pos - readStart);
                pos = readStart;

                // Read data into the buffer
                channel.position(pos);
                buffer.clear();
                channel.read(buffer);
                buffer.flip();  // Prepare the buffer for reading

                // Process the buffer content from the end backwards
                for (int i = readSize - 1; i >= 0; i--) {
                    char c = (char) buffer.get(i);
                    if (c == '\n') {
                        if (currentLine.length() > 0) {
                            result.addFirst(currentLine.reverse().toString());
                            currentLine.setLength(0);  // Clear the buffer
                            lineCount++;
                        }
                        if (lineCount == n) {
                            return result;  // Stop if we have the required number of lines
                        }
                    } else {
                        currentLine.append(c);
                    }
                }
            }

            // Add the remaining line if the file doesn't end with a newline
            if (currentLine.length() > 0) {
                result.addFirst(currentLine.reverse().toString());
            }
        }
        
        return result;
    }

    public static void main(String[] args) {
        try {
            String fileName = "your_static_file.txt";  // Replace with your file path
            int n = 100;  // Number of lines to retrieve
            Deque<String> lastLines = tail(fileName, n);

            for (String line : lastLines) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Leave a Comment