public class FlamByteInterface extends Object
This interface provides byte-wise or record-oriented sequential read and write access to original files. Original files can be normal clear binary, text or xml data sets as well as GZIP-, BZIP2-, XZ-, FLAM4 files or any other kind of original data stream format supported by FLAM. It includes all conversion and formatting capabilities of the Frankenstein Limes Universal Converter (FLUC).
It provides functions similar to the byte-wise file I/O functions in C. Only the file open function differs in that it takes a filename string and a format string. You can define them using the syntax of our command line (FLCL).
On read: The file definition string defines the read operation to be used to produce a neutral FLAM5 element list from the original data. The format string describes how this element list will then be formatted for sequential byte or record access.
On write: The format string defines how the provided byte stream or records will be formatted into a FLAM5 element list. The file definition string describes how this element list will be written to a file.
On read or write, you can define how to format the data (binary, character, text, xml, ...), use up to 32 different conversions (Base64, OpenPGP, GZIP, CHRSET, ...) executed sequentially and different kinds of I/O methods (block, record, text, FLAM4, ...). This means you can read and write compressed, encrypted and encoded files, where you can change the character set and other things as part of the write and read operation.
The FLAM element list is a neutral list of parsed data elements with a type,
a length, a value and some attributes. If the element data contains printable
characters, then these characters are encoded in UTF-8. Through the format
string, you define how this neutral list of elements is transformed into a
sequential data stream or records. For example, if the list contains text
elements, you can define which delimiter to add after each element, which
character set the output should be in and so on. Please use the interactive
help function (getHelp(HelpSubject, int, String)
) for more
information.
For stream-oriented data handling, you can choose between binary, character, text and XML formatting. For read operation, you can use the auto detection capabilities. For example:
FlamByteInterface if = new FlamByteInterface(); if.openRead("read.file='filename'","format.record()");
This results in each kind of file (encoded, encrypted and or compressed) being converted to records. If the content is XML, then the XML data is pretty printed into records. If it is text, then the data is parsed based on the containing delimiters. If it is binary and record lengths are detected, then the records are provided 1 by 1. If it is binary and no record lengths are known, then the data is wrapped into records.
If you use record formatting, then the read and write functions are not operating like in stream-oriented I/O. Instead, the behavior is more similar to the fread() and fwrite() operations on z/OS with 'type=record', except that you can define whether the record will be truncated (size!=0) or a length error occurs (size==0) to realize a reallocation schema.
The record formatting can be useful for normal text files to read the text record-by-record without the delimiters and zero termination at the end.
For all default conversions, it is useful to define the environment variable LANG. Other used environment variables of FLAM can be found in the FLCL manual.
The interface also provides access to the info command. This can be used, for example, to get information about files and supported CCSIDs.
Then function openRead(String, String)
returns a String containing
some internal state of FLUC. It can be passed to
openWrite(String, String, String)
. This is required to set the file
attributes of the source in archive headers like GZIP and FLAM. To get some
statistics when closing a file, you can call close(StatisticFormat)
or close(boolean, StatisticFormat)
.
The byte interface is thread-safe on all supported platforms except USS on zSeries. On classical mainframe operating systems like z/OS, threads are not supported but the interface is in general reentrant and can be used in parallel by different processes.
Note: An object of this class can only open one file at a time. However, an existing object can be reused after properly closing a previously opened file.
Constructor and Description |
---|
FlamByteInterface()
Creates an instance for reading or writing files using the FLAM byte
interface.
|
FlamByteInterface(Charset charset)
Creates an instance for reading or writing files using the FLAM byte
interface.
|
Modifier and Type | Method and Description |
---|---|
void |
close()
Closes the file previously opened.
|
String |
close(boolean success,
StatisticFormat statsFormat)
Closes the file previously opened.
|
String |
close(StatisticFormat statsFormat)
Closes the file previously opened.
|
void |
flush()
Flushes all internal buffers, i.e.
|
String |
getAbout()
Returns a string with about information for this library
on multiple lines and license information for used external
libraries.
|
String |
getErrorMessage()
Retrieves a human-readable message for the last error
|
String |
getErrorTrace()
Retrieves the FLAM error trace for the last error
|
String |
getHelp(HelpSubject what,
int depth,
String path)
Returns help information about the file and format strings.
|
String |
getInfo(String infoString,
InfoFormat format)
Retrieves various information about files, supported CCSIDs and
other things.
|
String |
getLicense()
Returns the current license text on multiple lines.
|
String |
getSyntax(HelpSubject what,
int depth,
String path)
Returns syntax information about the file and format strings.
|
String |
getVersion()
Returns a string with version information for each used component.
|
boolean |
hasError()
Checks whether a previous operation resulted in an error state.
|
boolean |
isEof()
Checks whether the end-of-file has been reached
|
boolean |
isOpen()
Checks whether this object holds an open file handle
|
static void |
loadLibrary()
Loads the native JNI-based library (flcbytjava) that backs the
functionality of this class.
|
static void |
loadLibrary(String dllPath)
Loads the native JNI-based library that backs the functionality
of this class from the file specified by the path passed as
argument.
|
String |
openRead(String fileString,
String formatString)
Uses the native FLAM byte interface (written in C) to open a normal file,
a member in a FLAM4FILE, a GZIP file or a member in a concatenated GZIP-,
BZIP- or XZ-File or any other supported file format for reading.
|
void |
openWrite(String fileString,
String formatString,
String state)
Uses the native FLAM byte interface (written in C) to open a normal file,
a member in a FLAM4FILE, a GZIP file or a member in a concatenated GZIP-,
BZIP- or XZ-File or any other supported file format for writing.
|
int |
read(byte[] buffer)
This function reads up to buffer.length bytes from the file.
|
int |
read(byte[] buffer,
int offset,
int length)
This function reads up to length bytes from the file.
|
int |
readRecord(byte[] buffer,
boolean allowTruncate)
This is the same as
read(byte[]) , but with an additional parameter
to control truncation in record mode. |
int |
readRecord(byte[] buffer,
int offset,
int length,
boolean allowTruncate)
This is the same as
read(byte[], int, int) , but with an additional parameter
to control truncation in record mode. |
int |
write(byte[] buffer)
Writes all bytes from the buffer passed as parameter to the open file.
|
int |
write(byte[] buffer,
int offset,
int length)
Writes length bytes starting at offset from the buffer
passed as parameter to the open file.
|
public FlamByteInterface()
Creates an instance for reading or writing files using the FLAM byte
interface. It is backed by a native C library (flcbytjava) which must be
loaded prior to calling this constructor by calling either
loadLibrary()
or loadLibrary(String)
. Failing to do so
results in undefined (JVM-dependent) behavior.
This object takes care that all input and output strings passed or returned by this class' object are converted to/from the native character set as required by the backing native library.
This constructor internally initializes CharsetEncoder and CharsetDecoder
objects using the is the same charset as returned by
Charset.defaultCharset()
.
loadLibrary()
,
loadLibrary(String)
public FlamByteInterface(Charset charset)
Creates an instance for reading or writing files using the FLAM byte
interface. It is backed by a native C library (flcbytjava) which must be
loaded prior to calling this constructor by calling either
loadLibrary()
or loadLibrary(String)
. Failing to do so
results in undefined (JVM-dependent) behavior.
This object takes care that all input and output strings passed or returned by this class' object are converted to/from the native character set as required by the backing native library.
This constructor internally initializes CharsetEncoder and CharsetDecoder objects using the character set object passed as parameter.
charset
- A non-null Charset object that matches the character set
required by the native library (i.e. your system character
set)loadLibrary()
,
loadLibrary(String)
public static void loadLibrary()
System.loadLibrary("flcbytjava");If the library is already loaded, this method does nothing.
System.loadLibrary(String)
public static void loadLibrary(String dllPath)
System.load(fllPath);If the library is already loaded, this method does nothing.
dllPath
- Path to the (lib)flybytjava DLLSystem.load(String)
public String getVersion() throws CharacterCodingException
CharacterCodingException
- if converting the result string from the native
interface's character set failspublic String getAbout() throws CharacterCodingException
CharacterCodingException
- if converting the result string from the native
interface's character set failspublic String getLicense() throws CharacterCodingException
CharacterCodingException
- if converting the result string from the native
interface's character set failspublic String getInfo(String infoString, InfoFormat format) throws CharacterCodingException, FlamException
Retrieves various information about files, supported CCSIDs and other things. You must provide an info string to define which information to request. You can define the format in which the information will be output.
The info definition string uses the same syntax as the get method of the FLCL INFO command. The complete syntax and help can be retrieved with the corresponding functions below. The zero-terminated string must start with 'get.' followed by the corresponding method (file/ccsids/...).
Examples:"get.file='test.txt'" "get.ccsids"Please use:
'getHelp(HelpSubject.INFO, 10, NULL)' 'getSyntax(HelpSubject.INFO, 10, NULL)'for more information.
infoString
- Info string with GET instructionsformat
- Format of the output (LIST, XML, ...)CharacterCodingException
- if converting the parameter strings to the native interface's
character set fails or if converting the result string from the
native interface's character set failsFlamException
- if retrieving the requested information failspublic String openRead(String fileString, String formatString) throws CharacterCodingException, FlamException
Uses the native FLAM byte interface (written in C) to open a normal file, a member in a FLAM4FILE, a GZIP file or a member in a concatenated GZIP-, BZIP- or XZ-File or any other supported file format for reading. It supports base encoding, encryption, compression, character conversion and text formatting, among others.
The file definition string parameter uses the same syntax as the read method of the FLCL CONV command. The complete syntax and help can be obtained with the corresponding functions below. The string must start with 'read.' followed by the corresponding method (binary/char/text/flam4/xml/...).
Example:"read.text(file='test.txt')"Please call:
FlamByteInterface.getHelp(HelpSubject.READ_FILE, 10, null) FlamByteInterface.getSyntax(HelpSubject.READ_FILE, 10, null)for more information.
The format string uses the syntax of the 'format' union which was specifically designed for the byte interface to format a byte stream based on the FLAM elements. The string must start with 'format.' followed by the corresponding method.
Examples:"format.text(method=CRLF suptws ccsid='UTF-16LE')" "format.bin()" "format.char(ccsid=DEFAULT)" "format.record(ccsid='IBM-1141')"Please call:
getHelp(HelpSubject.READ_FORMAT, 10, null) getSyntax(HelpSubject.READ_FORMAT, 10, null)for more information.
The file string defines how the FLAM elements are read from the file. The format string defines how the FLAM elements are converted into a byte stream or records.
This function returns a string containing some internal state and can
be used to transfer attributes, values and other information from an
input file opened by openRead(String, String)
to an output file
opened by openWrite(String, String, String)
.
The state string contains mainly file attributes which must be known to fill header information for archives (GZIP, FLAM) correctly.
You can look up the state string syntax and help with the corresponding functions below. The string must start with 'state(' followed by the corresponding value definitions and closed with ')'. Example:"state(member='test.txt' recf=FBA recl=120)"Please use:
getHelp(HelpSubject.STATE, 10, null) getSyntax(HelpSubject.STATE, 10, null)for more information.
fileString
- A file string of the FLCL CONV syntax for read operationsformatString
- A format string specifying the resulting data formatopenWrite(String, String, String)
CharacterCodingException
- if converting the parameter strings to the native interface's
character set fails or if converting the result string from the
native interface's character set failsFlamException
- if the specified file cannot be openedIllegalArgumentException
- if fileString does not specify a read operation ("read." or
"input.")public void openWrite(String fileString, String formatString, String state) throws CharacterCodingException, FlamException
Uses the native FLAM byte interface (written in C) to open a normal file, a member in a FLAM4FILE, a GZIP file or a member in a concatenated GZIP-, BZIP- or XZ-File or any other supported file format for writing. It supports base encoding, encryption, compression, character conversion and text formatting, among others.
The file definition string parameter uses the same syntax as the write method of the FLCL CONV command. The complete syntax and help can be obtained with the corresponding functions below. The string must start with 'write.' followed by the corresponding method (binary/char/text/flam4/xml/...).
Example:"write.binary(file='test.gz' comp.gzip(level=BEST))"Please call:
FlamByteInterface.getHelp(HelpSubject.WRITE_FILE, 10, null) FlamByteInterface.getSyntax(HelpSubject.WRITE_FILE, 10, null)for more information.
The format string uses the syntax of the 'format' union which was specifically designed for the byte interface to format the byte stream into FLAM elements. The string must start with 'format.' followed by the corresponding method.
Examples:"format.text(method=CRLF suptws ccsid='UTF-16LE')" "format.bin()" "format.char(ccsid=DEFAULT)" "format.record(ccsid='IBM-1141')"Please call:
getHelp(HelpSubject.WRITE_FORMAT, 10, null) getSyntax(HelpSubject.WRITE_FORMAT, 10, null)for more information.
The file string defines how the FLAM elements are written to the file. The format string defines how your input data is converted into FLAM elements.
This function accepts an optional string containing internal state
information and can be used to transfer attributes, values and other
information from an input file opened by openRead(String, String)
to an output file opened by openWrite(String, String, String)
.
The state string contains mainly file attributes which must be known to fill header information for archives (GZIP, FLAM) correctly.
You can look up the state string syntax and help with the corresponding functions below. The string must start with 'state(' followed by the corresponding value definitions and closed with ')'. Example:"state(member='test.txt' recf=FBA recl=120)"Please use:
getHelp(HelpSubject.STATE, 10, null) getSyntax(HelpSubject.STATE, 10, null)for more information.
fileString
- A file string of the FLCL CONV syntax for write operationsformatString
- A format string specifying the input data formatstate
- An optional string containing internal state information, may be nullCharacterCodingException
- if converting the parameter strings to the native interface's
character set failsFlamException
- if the specified file cannot be openedIllegalArgumentException
- if fileString does not specify a write operation ("write." or
"output.")public boolean isOpen()
public void close() throws FlamException
FlamException
- if closing the file fails for any reasonpublic String close(StatisticFormat statsFormat) throws FlamException, CharacterCodingException
Closes the file previously opened. All internal buffers are flushed and resources are released. Does nothing, if isOpen() returns false.
This function returns statistics about this file in the requested format.
statsFormat
- The format of the returned statisticsFlamException
- if closing the file fails for any reasonCharacterCodingException
- if converting the statistics string from the native interface's
character set failspublic String close(boolean success, StatisticFormat statsFormat) throws FlamException, CharacterCodingException
Closes the file previously opened. All internal buffers are flushed and resources are released. Does nothing, if isOpen() returns false.
This function returns statistics about this file in the requested format.
The success flag is only relevant in read mode. It allows you to
indicate whether the operation using the file was successful from the
caller's (i.e. your) point-of-view. If you set the 'remove' flag in the
file string passed to openRead(String, String)
, the file is only
removed if you indicate success, i.e. pass true for the success parameter.
In case of an error while processing the read data, it may be more
reasonable to keep the file, even though it was flagged for deletion.
success
- True indicates that the data was processed successfully by the callerstatsFormat
- The format of the returned statisticsFlamException
- if closing the file fails for any reasonCharacterCodingException
- if converting the statistics string from the native interface's
character set failspublic void flush() throws FlamException
FlamException
- if flushing failspublic int read(byte[] buffer)
This function reads up to buffer.length bytes from the file. It may return fewer bytes when the end-of-file (EOF) is encountered or if a record-oriented method is used for formatting.
In record-oriented mode (format.record()), the function reads
only one record on each call. If the provided buffer is too short to
hold the complete record, the record data is truncated and the remainder
of the record will be lost. If you do not want record data to be trunked,
please use readRecord(byte[], boolean)
.
There is no limit on record length in 'format.record()', but the record length may be limited by the underlining data management system (DMS) if you use 'read.record()' or 'write.record()'. Most record-oriented DMS are limited to a maximum record length of 32760 bytes. The record I/O of FLAM has a limit of 65535 bytes for the maximum record length.
Attention: If record I/O is used, then the returned number of bytes could be zero because records can contain zero-length data.
buffer
- A buffer used to read up to buffer.length bytesIllegalStateException
- if no file has been opened for readingopenRead(String, String)
public int read(byte[] buffer, int offset, int length)
This function reads up to length bytes from the file. It may return fewer bytes when the end-of-file (EOF) is encountered or if a record-oriented method is used for formatting.
In record-oriented mode (format.record()), the function reads
only one record on each call. If the provided buffer is too short to
hold the complete record, the record data is truncated and the remainder
of the record will be lost. If you do not want record data to be trunked,
please use readRecord(byte[], int, int, boolean)
.
There is no limit on record length in 'format.record()', but the record length may be limited by the underlining data management system (DMS) if you use 'read.record()' or 'write.record()'. Most record-oriented DMS are limited to a maximum record length of 32760 bytes. The record I/O of FLAM has a limit of 65535 bytes for the maximum record length.
Attention: If record I/O is used, then the returned number of bytes could be zero because records can contain zero-length data.
buffer
- A buffer used to read up to buffer.length bytesoffset
- An offset in buffer where to put the first byte readlength
- The number of bytes to requestIllegalStateException
- if no file has been opened for readingIllegalArgumentException
- if offset<0, length<0 or offset+length>buffer.lengthopenRead(String, String)
public int readRecord(byte[] buffer, boolean allowTruncate)
This is the same as read(byte[])
, but with an additional parameter
to control truncation in record mode. You should use this method if you
read a file in record-oriented mode (format.record()) and want to have
control over record truncation.
If true, the allowTruncate parameter enables truncation of records
if the provided buffer is too small to hold the complete record. If false,
an IndexOutOfBoundsException
is thrown if the buffer is
too short. You can then retry with a larger buffer as the internal record
pointer is not advanced.
buffer
- A buffer used to read up to buffer.length bytesallowTruncate
- true = allow truncation, false = exception if buffer too smallIllegalStateException
- if no file has been opened for readingIndexOutOfBoundsException
- if buffer is too short to hold the complete recordopenRead(String, String)
public int readRecord(byte[] buffer, int offset, int length, boolean allowTruncate)
This is the same as read(byte[], int, int)
, but with an additional parameter
to control truncation in record mode. You should use this method if you
read a file in record-oriented mode (format.record()) and want to have
control over record truncation.
If true, the allowTruncate parameter enables truncation of records
if the provided buffer is too small to hold the complete record. If false,
an IndexOutOfBoundsException
is thrown if the buffer is
too short. You can then retry with a larger buffer as the internal record
pointer is not advanced.
buffer
- A buffer used to read up to buffer.length bytesoffset
- An offset in buffer where to put the first byte readlength
- The number of bytes to requestallowTruncate
- true = allow truncation, false = exception if buffer too smallIllegalStateException
- if no file has been opened for readingIndexOutOfBoundsException
- if buffer is too short to hold the complete recordIllegalArgumentException
- if offset<0, length<0 or offset+length>buffer.lengthopenRead(String, String)
public int write(byte[] buffer)
Writes all bytes from the buffer passed as parameter to the open file. Depending on the formatting method, the length of the data is either recorded or discarded.
When a record-oriented formatting method is used, each call to
write(byte[])
is transformed into one record. Only one record can be
written per call when using record I/O. The record length is not
limited when formatting the elements in memory. However, when writing
records to a dataset or a FLAMFILE, respective limits apply. Therefore,
in the file string, you can define how longer records are handled.
buffer
- The bytes to writeIllegalStateException
- if no file is openIllegalArgumentException
- if offset<0, length<0 or offset+length>buffer.lengthpublic int write(byte[] buffer, int offset, int length)
Writes length bytes starting at offset from the buffer passed as parameter to the open file. Depending on the formatting method, the length of the data is either recorded or discarded.
When a record-oriented formatting method is used, each call to
write(byte[])
is transformed into one record. Only one record can be
written per call when using record I/O. The record length is not
limited when formatting the elements in memory. However, when writing
records to a dataset or a FLAMFILE, respective limits apply. Therefore,
in the file string, you can define how longer records are handled.
buffer
- The bytes to writeoffset
- Offset of the first byte to write in bufferlength
- Number of bytes to writeIllegalStateException
- if no file is openIllegalArgumentException
- if offset<0, length<0 or offset+length>buffer.lengthpublic boolean isEof()
IllegalStateException
- if this object does not denote an open filepublic boolean hasError()
getErrorMessage()
or an error trace with
getErrorTrace()
public String getErrorMessage() throws CharacterCodingException
CharacterCodingException
- if converting the error string from the native interface's
character set failspublic String getErrorTrace() throws CharacterCodingException
CharacterCodingException
- if converting the trace string from the native interface's
character set failspublic String getHelp(HelpSubject what, int depth, String path) throws CharacterCodingException
getSyntax(HelpSubject, int, String)
to see possible aliases for the same argument.what
- The type of file or format string to get help fordepth
- Number of levels to display (0-Man page, 1-One Level, 2-Two Level, ..., <9-All)path
- Path (e.g. read.text.ccsid) to limit help to the (sub)tree of a certain objectCharacterCodingException
- if converting the parameter strings to the native interface's
character set fails or if converting the result string from the
native interface's character set failspublic String getSyntax(HelpSubject what, int depth, String path) throws CharacterCodingException
what
- The type of file or format string to get the syntax fordepth
- Number of levels to display (0-Man page, 1-One Level, 2-Two Level, ..., <9-All)path
- Path (e.g. read.text.ccsid) to limit syntax to the (sub)tree of a certain objectCharacterCodingException
- if converting the parameter strings to the native interface's
character set fails or if converting the result string from the
native interface's character set fails