public class LargeAsciiTable
extends java.lang.Object
implements java.lang.AutoCloseable
An object of this class manages a large ASCII table: it receives (non-empty)
lines to add. Each of these lines is made of columns separated by a given
separator char. Columns can be aligned (RIGHT
, LEFT
or
CENTER
) before usage.
A typical usage of this class is the following:
try(LargeAsciiTable
myTable = newLargeAsciiTable('|')
){ // First, set the header (if one is needed): myTable.addHeaderLine("col1|col2")
; // Then add lines: myTable.addLine("val1.1|val1.2")
; myTable.addLine("val2.1|val2.2")
; // ... // End the table: myTable.endTable()
; // Display in the standard output stream the aligned table:LargeAsciiTable.LineProcessor
showLine = new LineProcessor(){ public boolean process(final String alignedLine) throws LineProcessorException{ System.out.println(alignedLine); return true; } }; final int[] alignmentPolicy = new int[]{RIGHT
,CENTER
}; myTable.streamAligned(showLine, alignmentPolicy)
; }
AsciiTable
vs LargeAsciiTable
The main difference between an AsciiTable
and a
LargeAsciiTable
is how both are storing the table.
AsciiTable
is keeping the table entirely in memory, while
LargeAsciiTable
uses a temporary file after a given number of lines
(see DEFAULT_MEMORY_THRESHOLD
). Consequently, using
AsciiTable
for large tables will consume a lot of memory and my
trigger an Out Of Memory error. Hence this LargeAsciiTable
variant,
better suited for such tables.
Note:
It is possible to change the memory threshold ONLY at creation
(LargeAsciiTable(char, int)
) and when reseting a table
(reset(char, int)
).
AsciiTable | LargeAsciiTable |
---|---|
displayRaw(char) |
streamRaw(LineProcessor, char) |
displayAligned(int[], char, Thread) |
streamAligned(LineProcessor, int[], char, Thread) |
Instead of returning every lines in a String array, LargeAsciiTable
returns the number of processed lines. Each line can be accessed/processed
thanks to the given LargeAsciiTable.LineProcessor
. In this way, only memory required
for the current line is used in the JVM.
Because we may now rely on a file, it is required to close the table and
delete the file once the large ASCII table is no longer needed. This can
be achieved by the function close()
.
Note 1:
This class implements the interface AutoCloseable
. This makes
the creation and resources release much easier:
try(LargeAsciiTable
myLargeTable = new LargeAsciiTable('|')){
...
}
Note 2:
Once a LargeAsciiTable
is closed, no more line can be added or
accessed. But, it is possible to reuse the same instance to build another
table. For that, one must use the function reset(char)
.
In addition, in order to ensure data consistency, it is required to declare
when the table content is complete. See endTable()
.
Modifier and Type | Class and Description |
---|---|
static interface |
LargeAsciiTable.AsciiTableIterator
An auto-closeable iterator for
LargeAsciiTable . |
static interface |
LargeAsciiTable.LineProcessor
Object letting process any given line.
|
static class |
LargeAsciiTable.LineProcessorException
Exception thrown when processing a line streamed by
LargeAsciiTable . |
Modifier and Type | Field and Description |
---|---|
protected java.io.File |
bufferFile
File containing all the lines previously added and not fitting in memory
according to
memoryThreshold . |
static int |
CENTER
Flag to center align a column content.
|
protected boolean |
closed
Indicate whether this table is closed.
|
protected boolean |
complete
Indicate whether this table is complete.
|
protected char |
csep
Column separator (as char).
|
static int |
DEFAULT_MEMORY_THRESHOLD
Default number of lines to keep in memory.
|
protected boolean |
empty
Indicate whether this table is empty.
|
protected static java.lang.String |
ERROR_HEADER_CLOSED
Error message returned when the header of a table was expected to be
still open.
|
protected static java.lang.String |
ERROR_NO_MORE_LINE
Error message returned when no more line can be got in an
LargeAsciiTable.AsciiTableIterator . |
protected static java.lang.String |
ERROR_TABLE_CLOSED
Error message returned when a table was expected to be open.
|
protected static java.lang.String |
ERROR_TABLE_COMPLETE
Error message returned when a table was expected to be IN-complete.
|
protected static java.lang.String |
ERROR_TABLE_NOT_COMPLETE
Error message returned when a table was expected to be complete.
|
protected java.lang.String |
headerPostfix
String separating the header from the table lines.
|
protected int |
headerSize
Number of lines in the header.
|
protected java.lang.StringBuffer |
HSEP
Buffer of column separators to use when formatting a line.
|
static int |
LEFT
Flag to left align a column content.
|
protected java.lang.String[] |
lines
List of lines ONLY IF the complete table fits in memory (defined by
memoryThreshold ). |
protected int |
memoryThreshold
Maximum number of lines that can be hold in memory.
|
protected int |
nbLines
Number of lines currently stored in memory -
lines . |
protected long |
nbTotalLines
Number of lines stored in this table (in memory + on disk, if used).
|
protected java.io.ObjectOutputStream |
out
Stream used to update the buffer file.
|
static int |
RIGHT
Flag to right align a column content.
|
protected java.lang.String |
sep
Column separator (as string).
|
protected int[] |
sizes
Size of the columns.
|
protected java.lang.StringBuffer |
SPACES
Buffer of spaces to use when aligning a column value.
|
Constructor and Description |
---|
LargeAsciiTable(char separ)
Constructor.
|
LargeAsciiTable(char separ,
int memoryThreshold)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
boolean |
addHeaderLine(java.lang.String headerline)
Add a header line.
|
protected void |
addHsep(java.lang.StringBuffer buf,
int nb)
Add horizontal separator chars to the StringBuffer.
|
boolean |
addLine(java.lang.String line)
Add a line to the table.
|
protected void |
addspaces(java.lang.StringBuffer buf,
int nb)
Add nb spaces to the StringBuffer.
|
protected void |
appendToBufferFile()
Append all the memorised lines at the end of the buffer file.
|
void |
close()
Free all resources associated with this
LargeAsciiTable :
close the output stream toward the temporary buffer file, if open,
delete the temporary buffer file,
discard all memorised lines,
and forget about the given header Postfix and spaces.
|
void |
endTable()
Declare this table as complete.
|
java.lang.String |
getHeaderPostfix()
Get the separator between the header and the table lines.
|
LargeAsciiTable.AsciiTableIterator |
getIterator()
Let iterate over the complete content of this table.
|
int |
getMemoryThreshold()
Get the number of lines above which the entire table will be stored on
disk (in a temporary file).
|
int |
headerSize()
Get the number of lines composing the header block of this table.
|
void |
reset(char separ)
Reset this
LargeAsciiTable so that lines can be safely
added. |
void |
reset(char separ,
int memoryThreshold)
Reset this
LargeAsciiTable so that lines can be safely
added. |
void |
setHeaderPostfix(java.lang.String postfix)
Set the separator between the header and the table lines.
|
long |
size()
Get the number of lines stored in this
LargeAsciiTable instance. |
long |
streamAligned(LargeAsciiTable.LineProcessor lineProc,
int[] pos)
Give to the given
LargeAsciiTable.LineProcessor all lines in which all columns
are aligned. |
long |
streamAligned(LargeAsciiTable.LineProcessor lineProc,
int[] pos,
char newsep)
Give to the given
LargeAsciiTable.LineProcessor all lines in which all columns
are aligned. |
long |
streamAligned(LargeAsciiTable.LineProcessor lineProc,
int[] pos,
char newsep,
java.lang.Thread thread)
Give to the given
LargeAsciiTable.LineProcessor all lines in which all columns
are aligned. |
long |
streamRaw(LargeAsciiTable.LineProcessor lineProc)
Give to the given
LargeAsciiTable.LineProcessor all the lines without alignment,
as they were added. |
long |
streamRaw(LargeAsciiTable.LineProcessor lineProc,
char newsep)
Give to the given
LargeAsciiTable.LineProcessor all the lines without alignment,
as they were added, potentially with some separator control. |
java.lang.String |
toString()
Return the whole table, with left alignment on all columns.
|
public static final int LEFT
public static final int CENTER
public static final int RIGHT
protected static final java.lang.String ERROR_TABLE_COMPLETE
protected static final java.lang.String ERROR_TABLE_NOT_COMPLETE
protected static final java.lang.String ERROR_TABLE_CLOSED
protected static final java.lang.String ERROR_HEADER_CLOSED
protected static final java.lang.String ERROR_NO_MORE_LINE
LargeAsciiTable.AsciiTableIterator
.
This error is generally thrown by the next() function.public static final int DEFAULT_MEMORY_THRESHOLD
memoryThreshold
,
Constant Field Valuesprotected int memoryThreshold
If more lines are added, this LargeAsciiTable
will store all
lines in a temporary file.
By default set to 1000 lines.
protected java.lang.String[] lines
memoryThreshold
). If not, the table is stored in a temporary
file: bufferFile
.
Important:
No empty and NULL lines are allowed in this array.
All the functions of LargeAsciiTable
relies on this rule ;
breaking it may trigger the generation of NullPointerException at some
point.
protected int nbLines
lines
.protected long nbTotalLines
protected boolean empty
protected int headerSize
Important:
The header lines are always the lines starting the table.
All lines from headerSize
(included) are the table lines/data.
protected java.lang.String headerPostfix
protected boolean complete
true
if no more lines can be added.
protected boolean closed
A closed table has no content and uses as less as memory as possible.
Important:
In order to use a closed table, one must call reset(char)
first.
protected java.io.File bufferFile
memoryThreshold
.
If NULL, no file has been used.
protected java.io.ObjectOutputStream out
NULL if no buffer file is used or if this table is closed.
protected java.lang.StringBuffer SPACES
Note:
It can be extended by addspaces(StringBuffer, int)
if needed.
protected java.lang.StringBuffer HSEP
Note:
It can be extended by addHsep(StringBuffer, int)
if needed.
protected int[] sizes
protected char csep
protected java.lang.String sep
public LargeAsciiTable(char separ)
separ
- Character defining the column separator in the input lines.public LargeAsciiTable(char separ, int memoryThreshold)
separ
- Character defining the column separator in the
input lines.memoryThreshold
- Maximum number of lines that can be hold in
memory. If more lines are added, the whole table
will be temporarily stored on disk.
If ≤ 0, it is automatically set to
1000 lines.public final long size()
LargeAsciiTable
instance.
Note: The returned number includes the size of the header and the separator line (only if there is a header block).
public final int headerSize()
Note: The returned number does not include the separator line.
public final int getMemoryThreshold()
Important:
This threshold can be set only when
creating
or
reseting
a LargeAsciiTable
.
public final java.lang.String getHeaderPostfix()
public final void setHeaderPostfix(java.lang.String postfix)
postfix
- String to append after the header lines.public final void reset(char separ)
LargeAsciiTable
so that lines can be safely
added.
Warning!
This function starts by closing this LargeAsciiTable
. Thus, all
lines already stored inside it will be completely discarded/lost.
separ
- Character defining the column separator in the
input lines.public void reset(char separ, int memoryThreshold)
LargeAsciiTable
so that lines can be safely
added.
Warning!
This function starts by closing this LargeAsciiTable
. Thus, all
lines already stored inside it will be completely discarded/lost.
separ
- Character defining the column separator in the
input lines.memoryThreshold
- Maximum number of lines that can be hold in
memory. If more lines are added, the whole table
will be temporarily stored on disk.
If ≤ 0, it is automatically set to
1000 lines.public void close()
LargeAsciiTable
:
Note:
Once closed, a LargeAsciiTable
can be re-used to store another
table. For that, call the function reset(char)
(which by
default starts by calling close()
).
close
in interface java.lang.AutoCloseable
AutoCloseable.close()
public java.lang.String toString()
Warning!
This operation is very likely to consume a lot of memory as the table
will have to fit entirely in memory, in a single String.
In such case, it is possible to stop this function call by
interrupting (cf Thread.interrupt()
) the thread running it.
toString
in class java.lang.Object
public boolean addHeaderLine(java.lang.String headerline) throws java.io.IOException, java.lang.IllegalStateException
headerline
- Header line to add.java.io.IOException
- If there is any error while updating
this table header.java.lang.IllegalStateException
- If this LargeAsciiTable
is
closed or already complete.public void endTable() throws java.io.IOException
Warning:
Once this function called, it is no longer possible to add new line to
this LargeAsciiTable
instance. Any further call to functions
like addLine(String)
will throw an
IllegalStateException
.
Note: Calling this function on an already complete table has no effect.
java.io.IOException
- If there is an error while closing the buffer file.public boolean addLine(java.lang.String line) throws java.io.IOException, java.lang.IllegalStateException
Important: The line should not end up with a newline char. If it is the case, alignment errors can be experienced depending on the alignment type of the last column.
Warning! This function determines the number of columns ONLY with the first added line. Consequently, if some lines have a different number of columns, the measured size of all table columns may be unexpected. This is especially true in the two following cases:
line
- String containing the line with all the columns separated by
the column separator.java.io.IOException
- If there is any error while updating
this table content.java.lang.IllegalStateException
- If this LargeAsciiTable
is
closed or already complete.protected void appendToBufferFile() throws java.io.IOException
Note: If the buffer file does not exist yet, it will be created.
java.io.IOException
- If there is an error while creating or opening the
buffer file, or when writing inside it.public final long streamRaw(LargeAsciiTable.LineProcessor lineProc) throws java.lang.IllegalStateException, LargeAsciiTable.LineProcessorException, java.io.IOException, java.lang.InterruptedException
LargeAsciiTable.LineProcessor
all the lines without alignment,
as they were added.
Note:
This function does nothing and returns -1
if no
LargeAsciiTable.LineProcessor
is provided.
lineProc
- The action to perform on each line.java.lang.IllegalStateException
- If this LargeAsciiTable
is not
complete (i.e. if endTable()
has not been called before this
function).java.lang.InterruptedException
- If the current thread has been
interrupted.
This interruption is useful to stop
this streaming operation whenever it
becomes time and memory consuming.LargeAsciiTable.LineProcessorException
- If there was an error while processing
a line.
A such exception is generally thrown
by the given LargeAsciiTable.LineProcessor
.java.io.IOException
- If there is any error while accessing
the buffer file, or while processing a
line (if this processing implies I/O).public long streamRaw(LargeAsciiTable.LineProcessor lineProc, char newsep) throws java.lang.IllegalStateException, LargeAsciiTable.LineProcessorException, java.io.IOException, java.lang.InterruptedException
LargeAsciiTable.LineProcessor
all the lines without alignment,
as they were added, potentially with some separator control.
Note:
This function does nothing and returns -1
if no
LargeAsciiTable.LineProcessor
is provided.
lineProc
- The action to perform on each line.newsep
- Separator to use, replacing the original one.-1
if nothing has been done.java.lang.IllegalStateException
- If this LargeAsciiTable
is not
complete (i.e. if endTable()
has not been called before this
function).java.lang.InterruptedException
- If the current thread has been
interrupted.
This interruption is useful to stop
this streaming operation whenever it
becomes time and memory consuming.LargeAsciiTable.LineProcessorException
- If there was an error while processing
a line.
A such exception is generally thrown
by the given LargeAsciiTable.LineProcessor
.java.io.IOException
- If there is any error while accessing
the buffer file, or while processing a
line (if this processing implies I/O).public final long streamAligned(LargeAsciiTable.LineProcessor lineProc, int[] pos) throws java.lang.IllegalStateException, LargeAsciiTable.LineProcessorException, java.io.IOException, java.lang.InterruptedException
LargeAsciiTable.LineProcessor
all lines in which all columns
are aligned.
IMPORTANT:
The array - pos - should have as many columns as the table has. Each
column can contain either LEFT
,
CENTER
or
RIGHT
.
LEFT
alignment will be used.
Note:
This function does nothing and returns -1
if no
LargeAsciiTable.LineProcessor
is provided.
lineProc
- The action to perform on each line.pos
- Array of flags, indicating how each column should be
justified.size()
in order to know whether all lines were
successfully aligned and processed.java.lang.IllegalStateException
- If this LargeAsciiTable
is not
complete (i.e. if endTable()
has not been called before this
function).java.lang.InterruptedException
- If the current thread has been
interrupted.
This interruption is useful to stop
this alignment operation whenever it
becomes time and memory consuming.LargeAsciiTable.LineProcessorException
- If there was an error while processing
a line.
A such exception is generally thrown
by the given LargeAsciiTable.LineProcessor
.java.io.IOException
- If there is any error while accessing
the buffer file, or while processing a
line (if this processing implies I/O).public final long streamAligned(LargeAsciiTable.LineProcessor lineProc, int[] pos, char newsep) throws java.lang.IllegalStateException, LargeAsciiTable.LineProcessorException, java.io.IOException, java.lang.InterruptedException
LargeAsciiTable.LineProcessor
all lines in which all columns
are aligned.
IMPORTANT:
The array - pos - should have as many columns as the table has. Each
column can contain either LEFT
,
CENTER
or
RIGHT
.
LEFT
alignment will be used.
Note:
This function does nothing and returns -1
if no
LargeAsciiTable.LineProcessor
is provided.
lineProc
- The action to perform on each line.pos
- Array of flags, indicating how each column should be
justified.newsep
- Separator to use, replacing the original one.size()
in order to know whether all lines were
successfully aligned and processed.java.lang.IllegalStateException
- If this LargeAsciiTable
is not
complete (i.e. if endTable()
has not been called before this
function).java.lang.InterruptedException
- If the current thread has been
interrupted.
This interruption is useful to stop
this alignment operation whenever it
becomes time and memory consuming.LargeAsciiTable.LineProcessorException
- If there was an error while processing
a line.
A such exception is generally thrown
by the given LargeAsciiTable.LineProcessor
.java.io.IOException
- If there is any error while accessing
the buffer file, or while processing a
line (if this processing implies I/O).public long streamAligned(LargeAsciiTable.LineProcessor lineProc, int[] pos, char newsep, java.lang.Thread thread) throws java.lang.IllegalStateException, LargeAsciiTable.LineProcessorException, java.io.IOException, java.lang.InterruptedException
LargeAsciiTable.LineProcessor
all lines in which all columns
are aligned.
IMPORTANT:
The array - pos - should have as many columns as the table has. Each
column can contain either LEFT
,
CENTER
or
RIGHT
.
LEFT
alignment will be used.
Note:
This function does nothing and returns -1
if no
LargeAsciiTable.LineProcessor
is provided.
lineProc
- The action to perform on each line.pos
- Array of flags, indicating how each column should be
justified.newsep
- Separator to use, replacing the original one.thread
- Thread to watch. If it is interrupted, this task should
be as well.size()
in order to know whether all lines were
successfully aligned and processed.java.lang.IllegalStateException
- If this LargeAsciiTable
is not
complete (i.e. if endTable()
has not been called before this
function).java.lang.InterruptedException
- If the current thread has been
interrupted.
This interruption is useful to stop
this alignment operation whenever it
becomes time and memory consuming.LargeAsciiTable.LineProcessorException
- If there was an error while processing
a line.
A such exception is generally thrown
by the given LargeAsciiTable.LineProcessor
.java.io.IOException
- If there is any error while accessing
the buffer file, or while processing a
line (if this processing implies I/O).protected void addspaces(java.lang.StringBuffer buf, int nb)
buf
- StringBuffer to modify.nb
- Number of spaces to add.protected void addHsep(java.lang.StringBuffer buf, int nb)
buf
- StringBuffer to modify.nb
- Number of chars to add.public LargeAsciiTable.AsciiTableIterator getIterator() throws java.lang.IllegalStateException
IMPORTANT:
This function fails if the table is not complete
(i.e. endTable()
has not yet been called) or is closed.
java.lang.IllegalStateException
- If this table is not complete
or is closed.