[РЕДАКТИРОВАТЬ]
По запросу я добавляю этот ответ к комментарию более позднего комментария: если вам часто требуется такое поведение, «более подходящим» решением, вероятно, является перемещение ваших журналов из текстовых файлов.в таблицы базы данных с помощью DBAppender (часть log4j 2).Тогда вы могли бы просто запросить последние записи.
[/ EDIT]
Я, вероятно, подхожу к этому несколько иначе, чем перечисленные ответы.
(1) Создайте подкласс изWriter
, который записывает закодированные байты каждого символа в обратном порядке:
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) Создайте подкласс log4j WriterAppender
, чей метод createWriter
будет переопределен для создания экземпляра ReverseOutputStreamWriter
.
(3) Создать подкласс log4j Layout
, чей метод format
возвращает строку журнала в обратном порядке символов:
public class ReversePatternLayout extends PatternLayout {
// constructors
public String format(LoggingEvent event) {
return new StringBuilder(super.format(event)).reverse().toString();
}
}
(4) Изменить мой файл конфигурации ведения журналаотправлять сообщения журнала в и «нормальный» файл журнала и «обратный» файл журнала.«Обратный» файл журнала будет содержать те же сообщения журнала, что и «обычный» файл журнала, но каждое сообщение будет записано в обратном направлении.(Обратите внимание, что кодировка «обратного» файла журнала не обязательно соответствует UTF-8 или даже любой кодировке символов.)
(5) Создайте подкласс InputStream
, который охватывает экземпляр RandomAccessFile
для чтения байтов файла в обратном порядке:
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
}
Теперь, если я хочу прочитать записи "обычного" файла журнала в обратном порядке, мне просто нужно создать экземплярReverseFileInputStream
, что дает ему файл журнала "admre".