All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.util.ReverseFileReader Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%L
 * Nuiton Utils
 * %%
 * Copyright (C) 2004 - 2011 CodeLutin, Chatellier Eric
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.util;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * Reverse file reader.
 *
 * Read file line by line for end of file to begin of file.
 *
 * @author chatellier
 */
public class ReverseFileReader implements Closeable {
    protected String filename;

    protected RandomAccessFile randomfile;

    protected long position;

    public ReverseFileReader(File file) throws IOException {
        // Open up a random access file
        randomfile = new RandomAccessFile(file, "r");
        // Set our seek position to the end of the file
        position = randomfile.length();

        // Seek to the end of the file
        randomfile.seek(position);
        //Move our pointer to the first valid position at the end of the file.
        String thisLine = randomfile.readLine();
        while (thisLine == null) {
            position--;
            randomfile.seek(position);
            thisLine = randomfile.readLine();
            randomfile.seek(position);
        }
    }

    public ReverseFileReader(String filename) throws IOException {
        this(filename != null ? new File(filename) : null);
    }

    /**
     * Read one line from the current position towards the beginning.
     *
     * @return the next line of text from this file, or null if end of file is
     *         encountered before even one byte is read.
     * @throws IOException if any pb while reading line
     */
    public String readLine() throws IOException {
        int thisCode;
        char thisChar;
        String finalLine = "";

        // If our position is less than zero already, we are at the beginning
        // with nothing to return.
        if (position < 0) {
            return null;
        }

        for (; ; ) {
            // we've reached the beginning of the file
            if (position < 0) {
                break;
            }
            // Seek to the current position
            randomfile.seek(position);

            // Read the data at this position
            thisCode = randomfile.readByte();
            thisChar = (char) thisCode;

            // If this is a line break or carrige return, stop looking
            if (thisCode == 13 || thisCode == 10) {
                // See if the previous character is also a line break character.
                // this accounts for crlf combinations
                randomfile.seek(position - 1);
                int nextCode = randomfile.readByte();
                if (thisCode == 10 && nextCode == 13
                    || thisCode == 13 && nextCode == 10) {
                    // If we found another linebreak character, ignore it
                    position = position - 1;
                }
                // Move the pointer for the next readline
                position--;
                break;
            } else {
                // This is a valid character append to the string
                finalLine = thisChar + finalLine;
            }
            // Move to the next char
            position--;
        }
        // return the line
        return finalLine;
    }

    @Override
    public void close() throws IOException {
        if (randomfile != null) {
            randomfile.close();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy