How to Read File from End to Start (In Reverse Order) in Java

How to read file from end to start (in reverse order) in Java?

As far as I understand, you try to read backwards line by line.
Suppose this is the file you try to read:

line1

line2

line3

And you want to write it to the output stream of the servlet as follows:

line3

line2

line1

Following code might be helpful in this case:

    List<String> tmp = new ArrayList<String>();

do {
ch = br.readLine();
tmp.add(ch);
out.print(ch+"<br/>");
} while (ch != null);

for(int i=tmp.size()-1;i>=0;i--) {
out.print(tmp.get(i)+"<br/>");
}

Read a file line by line in reverse order

[EDIT]

By request, I am prepending this answer with the sentiment of a later comment: If you need this behavior frequently, a "more appropriate" solution is probably to move your logs from text files to database tables with DBAppender (part of log4j 2). Then you could simply query for latest entries.

[/EDIT]

I would probably approach this slightly differently than the answers listed.

(1) Create a subclass of Writer that writes the encoded bytes of each character in reverse order:

public class ReverseOutputStreamWriter extends Writer {
private OutputStream out;
private Charset encoding;
public ReverseOutputStreamWriter(OutputStream out, Charset encoding) {
this.out = out;
this.encoding = encoding;
}
public void write(int ch) throws IOException {
byte[] buffer = this.encoding.encode(String.valueOf(ch)).array();
// write the bytes in reverse order to this.out
}
// other overloaded methods
}

(2) Create a subclass of log4j WriterAppender whose createWriter method would be overridden to create an instance of ReverseOutputStreamWriter.

(3) Create a subclass of log4j Layout whose format method returns the log string in reverse character order:

public class ReversePatternLayout extends PatternLayout {
// constructors
public String format(LoggingEvent event) {
return new StringBuilder(super.format(event)).reverse().toString();
}
}

(4) Modify my logging configuration file to send log messages to both the "normal" log file and a "reverse" log file. The "reverse" log file would contain the same log messages as the "normal" log file, but each message would be written backwards. (Note that the encoding of the "reverse" log file would not necessarily conform to UTF-8, or even any character encoding.)

(5) Create a subclass of InputStream that wraps an instance of RandomAccessFile in order to read the bytes of a file in reverse order:

public class ReverseFileInputStream extends InputStream {
private RandomAccessFile in;
private byte[] buffer;
// The index of the next byte to read.
private int bufferIndex;
public ReverseFileInputStream(File file) {
this.in = new RandomAccessFile(File, "r");
this.buffer = new byte[4096];
this.bufferIndex = this.buffer.length;
this.in.seek(file.length());
}
public void populateBuffer() throws IOException {
// record the old position
// seek to a new, previous position
// read from the new position to the old position into the buffer
// reverse the buffer
}
public int read() throws IOException {
if (this.bufferIndex == this.buffer.length) {
populateBuffer();
if (this.bufferIndex == this.buffer.length) {
return -1;
}
}
return this.buffer[this.bufferIndex++];
}
// other overridden methods
}

Now if I want to read the entries of the "normal" log file in reverse order, I just need to create an instance of ReverseFileInputStream, giving it the "revere" log file.

Read file in reverse order using java 8

This works for strings:

steam.collect(Collectors.toCollection(LinkedList::new))
.descendingIterator().forEachRemaining(System.out::println);

This is another example using ArrayList:

    List<String> list = steam.collect(Collectors.toCollection(ArrayList::new));
Collections.reverse(list);
list.forEach(System.out::println);

How to read a file, reverse the order, and write reverse order

i am not so sure about your environment, and how long the text might be. and i am also not so sure why you need a scanner?

anyway, here's my take on the problem, hope this helps you :)

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;

public class Reverse {

public static void main(String[] args) {

FileInputStream fis = null;
RandomAccessFile raf = null;

// by default, let's use utf-8
String characterEncoding = "utf-8";

// but if you pass an optional 3rd parameter, we use that
if(args.length==3) {
characterEncoding = args[2];
}

try{

// input file
File in = new File(args[0]);
fis = new FileInputStream(in);

// a reader, because it respects character encoding etc
Reader r = new InputStreamReader(fis,characterEncoding);

// an outputfile
File out = new File(args[1]);

// and a random access file of the same size as the input, so we can write in reverse order
raf = new RandomAccessFile(out, "rw");
raf.setLength(in.length());

// a buffer for the chars we want to read
char[] buff = new char[1];

// keep track of the current position (we're going backwards, so we start at the end)
long position = in.length();

// Reader.read will return -1 when it reached the end.
while((r.read(buff))>-1) {

// turn the character into bytes according to the character encoding
Character c = buff[0];
String s = c+"";
byte[] bBuff = s.getBytes(characterEncoding);

// go to the proper position in the random access file
position = position-bBuff.length;
raf.seek(position);

// write one or more bytes for the character
raf.write(bBuff);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// clean up
try {
fis.close();
} catch (Exception e2) {
}
try {
raf.close();
} catch (Exception e2) {
}
}

}

}


Related Topics



Leave a reply



Submit