org.nuiton.util.ReverseFileReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-utils Show documentation
Show all versions of nuiton-utils Show documentation
Library of usefull classes to be used in any project.
/*
* #%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();
}
}