cox.jmatt.java.MathTools.util
Class MathFileIO

java.lang.Object
  extended by cox.jmatt.java.MathTools.util.MathFileIO

public class MathFileIO
extends java.lang.Object

This class provides MathTools with file IO capability. Since Applets do not routinely have filesystem access, MTApplet does not have access to this class, nor will MathEngine create one. The zero-argument constructor of this class is private; at any given time there must be only one base instance of this class. Use the getInstance() method to retrieve it.

MathFileIO works by wrapping an I/O Object of some flavor: InputStream, OutputStream, Reader, or Writer. It handles all read/write calls and wraps any Exceptions thrown. More importantly, it keeps track of the open file references. When any or all need for file IO is gone, a call to closeAll() closes any open MathFileIO instances and makes them eligible for garbage collection. ScriptPanel handles this automatically but applications embedding and using this class must do it manually.

MathFileIO is designed to hide the grisly details of low-level file I/O from scripts, primarily, and from applications as needed. The class itself wraps around an IO Object and contains all methods necessary to interact with it. All Exceptions thrown are caught gracefully and reported at Error level, and anything opened is closed automatically, thus freeing resources when the script ends. (This is standard behavior for ScriptPanel but should be implemented in applications!)

As implied by its name, MathFileIO is designed to deal with files. By intent it was designed to deal with text files, as that is what MathTools generate, but basic machinery is supplied to work with files of other types. Byte[] and char[] arrays can be created and used for both input and output operations. This should be enough to allow binary or close-to-binary file manipulation. If a graphing.* implementation needs such machinery it is here.

In addition to simple files, MathFileIO can create InputStreams connected to resources. Scripts can use this to fetch files from the MathTools JAR or from a remote URL. The only downside is these methods create an InputStream: use toReader() to change this.

For advanced users MathFileIO provides the newRandomAccessFile() method. It requires a non-null, non-empty filename and a valid mode: 'r', 'rw', 'rws', or 'rwd'. Unlike the kinder gentler creation methods this one returns its RandomAccessFile live and raw. The only protection offered is ensuring that the filename and mode are not null or empty and proper closure from the closeAll() method. See the java.io.RandomAccessFile javadoc for further information. USE WITH CAUTION!

The final piece of equipment this class provides is directory processing. This works on file names only but comes with a great deal of power and flexibility. The basic process scans a specified directory and provides LOTS of information on the files it finds. This information appears as a rich set of formatting tokens applied to a template sent in as an argument, with the resulting Strings returned in an array. This processing can be done recursively and it allows for prefix-, suffix- and regex-filtering of the files it finds. In regex mode, the capture groups from the regular expression are also available as formatting tokens.


Method Summary
 void close_All()
          Instance version of closeAll().
 void close()
          Close this MFileIO instance.
static void closeAll()
          Close ALL currently-open MathFileIO instances.
 void flush()
          Flush the OutputStream or Writer encapsulated by this MFileIO.
 byte[] newByteArray(int pLength)
          Create and return a new byte[] array.
 char[] newCharArray(int pLength)
          Create and return a new char[] array.
 MathFileIO newInputStream(java.lang.String pFileName)
          Create an InputStream MathFileIO.
static MathFileIO newInstance()
          This method returns the base instance of MathFileIO.
static MathFileIO newInstance(java.lang.String pFileName, char pType)
          This method returns a new MathFileIO wrapped around whatever I/O Object and file are requested.
 MathFileIO newLoaderStream(java.lang.String pFileName)
          Use MathFileIO to get an InputStream connected to a specific resource using CapCom.getMathClassLoader().
 MathFileIO newOutputStream(java.lang.String pFileName)
          Create an OutputStream MathFileIO.
 java.io.RandomAccessFile newRandomAccessFile(java.lang.String pFileName, java.lang.String pMode)
          Create and return a java.io.RandomAccessFile.
 MathFileIO newReader(java.lang.String pFileName)
          Create a MathFileIO Reader.
 MathFileIO newResourceStream(java.lang.String pFileName)
          Use MathFileIO to get an InputStream connected to a specific resource.
 MathFileIO newWriter(java.lang.String pFileName)
          Create a MathFileIO Writer.
 java.lang.String[] process_Directory(java.lang.String pDir, java.lang.String pTemplate, boolean pRecursive)
          Instance shadow for the short method.
 java.lang.String[] process_Directory(java.lang.String pDir, java.lang.String pTemplate, boolean pRecursive, java.lang.String pStartsWith, java.lang.String pEndsWith, java.lang.String pRegex)
          Instance shadow for the full method.
static java.lang.String[] processDirectory(java.lang.String pDir, java.lang.String pTemplate, boolean pRecursive)
          Convenience method that only takes the first three parameters.
static java.lang.String[] processDirectory(java.lang.String pDir, java.lang.String pTemplate, boolean pRecursive, java.lang.String pStartsWith, java.lang.String pEndsWith, java.lang.String pRegex)
          This method provides powerful and flexible machinery for processing the filenames within a directory.
 int read()
          Read a byte or char of data, depending on the IO Object.
 int read(byte[] bData, int pOffset, int pLength)
          Read a sequence of bytes into an array.
 int read(char[] bData, int pOffset, int pLength)
          Read a sequence of char into an array.
 java.lang.String readLine()
          Read a line.
static void setDirProcTemplate(java.lang.String pTemplate)
          Set a default directory processing template.
 void setNewDirProcTemplate(java.lang.String pTemplate)
          Instance template-setting method.
 MathFileIO toReader()
          Convert an InputStream instance to a Reader.
 MathFileIO toWriter()
          Convert an OutputStream instance to a Writer.
 void write(byte[] pData, int pOffset, int pLength)
          Issue a write to the underlying OutputStream.
 void write(char[] pData, int pOffset, int pLength)
          Issue a write to the underlying Writer.
 void write(int pData)
          Write a single byte (OutputStream) or char (Writer) to the Output object.
 void write(java.lang.String pData)
          Write a String to the OutputStream or Writer.
 void writeLine(java.lang.String pLine)
          Write a String per the plain write() method BUT append a newline (OutputStream) or call newLine() (Writer).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

processDirectory

public static final java.lang.String[] processDirectory(java.lang.String pDir,
                                                        java.lang.String pTemplate,
                                                        boolean pRecursive,
                                                        java.lang.String pStartsWith,
                                                        java.lang.String pEndsWith,
                                                        java.lang.String pRegex)

This method provides powerful and flexible machinery for processing the filenames within a directory. It does not process the individual files, but rather allows their names to be taken and formatted per Question.fillTemplate() with a rich set of file- and filename-related replacement tokens. File names can be filtered three ways: prefix, suffix and regular expression. The first two use the String startsWith() and endsWith methods. The third filters by regular expression match AND provides extra formatting tokens based on the capture groups. These filtering methods are not mutually exclusive and can be combined. The logic used is exclusive, so prefix matching and regex matching MUST satisfy both conditions to be processed. Filtering is enabled by non-null values for the corresponding Strings; sending in null disables that type of matching.

If 'pRecursive' is set to 'true' all subdirectories of the one specified are processed as well. That is, they are processed recursively. In either recursive or non-recursive mode there is no guarantee made as to the order in which the filenames will appear. This method does keep a count of the number of files processed. This count is available as a number (long) via token #6. Tokens #7 and #8 also provide this counter as upper- and lowercase letters.

The standard formatting tokens are available for all files, regardless of filtering. Two java.io.File constants are provided for convenience. The 'index' tokens utilize a long value that begins at zero and increments by one with each file actually processed. The standard tokens are:

Tokens marked 'SX' depend on File methods that may throw a security exception. If that happens they will contain the literal String 'Exception' but the Exception itself is caught but not reported.

Tokens #14, #15 and #16 are provided for recursive processing. #14 contains the path (getPath()) of the directory specified with the method call. Token #15 contains the relative path to files 'beneath' the base directory. It consists of the file's getPath() String with the base directory removed. It does NOT include the separator between them! This token is blank for files processed in the base directory. Token #16 contains the java.io.File.separator constant when processing files in subdirectories and is blank for files within the base directory.

Tokens #17 through #19 are based on the ever-classic 'filename-dot-extension' naming convention. If a dot is present in the filename, token #17 holds everything before but not including the last dot and #19 holds everything after it. Token #18 holds a dot if both #17 and #19 contain non-empty Strings. If there is no dot or if it appears as the first character, #17 holds the entire filename and the other two tokens are blank.

In addition to the standard tokens defined above, which are valid for ALL files and matches, this method defines a set of Regular Expression Tokens. These Regex tokens begin with token 20 ('<20>)' and contain any matched capture groups. Token 20 is group zero and the values move up from there. These tokens result from the group(int) method Matcher defines with a (replacement token) offset of +20. This means token #20 (capture group zero) contains the entire pattern, #21 contains capture group 1 etc. These tokens are only defined during regular-expression matching! Any tokens with null values instead contain empty Strings.

Parameters:
pDir - The directory to process. If the String describes a file, its parent will be taken instead.
pTemplate - The template used to format the matched results.
pRecursive - Set 'true' to process the specified directory recursively, otherwise any subdirectories are ignored.
pStartsWith - Select only files that start with this String. If null it is ignored and no prefix-matching is done.
pEndsWith - Select only files that end with this. Ignored if null.
pRegex - If not null then all files are matched against this Regular Expression and capture groups are available for formatting. Ignored if null.

processDirectory

public static final java.lang.String[] processDirectory(java.lang.String pDir,
                                                        java.lang.String pTemplate,
                                                        boolean pRecursive)
Convenience method that only takes the first three parameters. No file filtering is done and all such arguments are null.


process_Directory

public java.lang.String[] process_Directory(java.lang.String pDir,
                                            java.lang.String pTemplate,
                                            boolean pRecursive,
                                            java.lang.String pStartsWith,
                                            java.lang.String pEndsWith,
                                            java.lang.String pRegex)
Instance shadow for the full method.


process_Directory

public java.lang.String[] process_Directory(java.lang.String pDir,
                                            java.lang.String pTemplate,
                                            boolean pRecursive)
Instance shadow for the short method.


setDirProcTemplate

public static final void setDirProcTemplate(java.lang.String pTemplate)
Set a default directory processing template. If pTemplate is null or blank, '<0>' is set.


setNewDirProcTemplate

public final void setNewDirProcTemplate(java.lang.String pTemplate)
Instance template-setting method.


newInstance

public static final MathFileIO newInstance()
This method returns the base instance of MathFileIO. It is a factory method: if no instance exists it creates one but if an instance does already exist this method returns a reference to it. This is done to allow proper closing and disposal of resources.


newInstance

public static final MathFileIO newInstance(java.lang.String pFileName,
                                           char pType)

This method returns a new MathFileIO wrapped around whatever I/O Object and file are requested. The options are:

Attempting to set anything other than one of these results in a null return. Also, if the filename is null or empty, null is returned. Any Exceptions are reported at Error level and the return value for such is null.

Parameters:
pFileName - The name of the file to be I/O'ed.
pType - One of the characters above, upper or lower case.
Returns:
A fresh MathFileIO ready for I/O, or null if something awful happened.

newInputStream

public MathFileIO newInputStream(java.lang.String pFileName)
Create an InputStream MathFileIO.


newOutputStream

public MathFileIO newOutputStream(java.lang.String pFileName)
Create an OutputStream MathFileIO.


newReader

public MathFileIO newReader(java.lang.String pFileName)
Create a MathFileIO Reader.


newWriter

public MathFileIO newWriter(java.lang.String pFileName)
Create a MathFileIO Writer.


newResourceStream

public MathFileIO newResourceStream(java.lang.String pFileName)
Use MathFileIO to get an InputStream connected to a specific resource. (Simple version.)


newLoaderStream

public MathFileIO newLoaderStream(java.lang.String pFileName)
Use MathFileIO to get an InputStream connected to a specific resource using CapCom.getMathClassLoader().


newRandomAccessFile

public java.io.RandomAccessFile newRandomAccessFile(java.lang.String pFileName,
                                                    java.lang.String pMode)
Create and return a java.io.RandomAccessFile. Unlike the other creation methods this one returns a live RandomAccessFile. There is no Exception-proofing or wrapping, the file itself is returned unwrapped. It is still tracked, so the closeAll() method will dispose of it but there is no other protection on it. USE WITH CAUTION!! If the filename or mode are empty or null the return value is null. If the mode is not valid the return value is null. Any creation errors are reported at the Error level.

Parameters:
pFileName - The name of the file to create or open.
pMode - The mode in which the file is to operate.

toReader

public MathFileIO toReader()
Convert an InputStream instance to a Reader. This has no effect on an output instance or an instance that already encapsulates a Reader. USE WITH CAUTION: This is a one-way trip and the underlying stream is lost in the conversion! Any errors are reported at Error level and the underlying stream is not affected. This method returns a self-reference.


toWriter

public MathFileIO toWriter()
Convert an OutputStream instance to a Writer. This has no effect on an input instance or an instance that already encapsulates a Writer. USE WITH CAUTION: This is a one-way trip and the underlying stream is lost in the conversion! Any errors are reported at Error level and the underlying stream is not affected. This method returns a reference to itself.


flush

public void flush()
Flush the OutputStream or Writer encapsulated by this MFileIO. If it is not an output instance, nothing happens. Multiple calls to this method will have no bad effects, even if it is an input Object. Any Exceptions thrown are reported at the Error level.


close

public void close()
Close this MFileIO instance. Any exceptions are reported at Error level. Note: This method does NOT automatically flush() OutputStreams or Writers!


closeAll

public static final void closeAll()
Close ALL currently-open MathFileIO instances.


close_All

public void close_All()
Instance version of closeAll().


newByteArray

public byte[] newByteArray(int pLength)
Create and return a new byte[] array. If the requested length is less than one, the array '{0}' is returned. NOTE: The array is created but NOT filled!


newCharArray

public char[] newCharArray(int pLength)
Create and return a new char[] array. If the requested length is less than one, '{0}' is returned. NOTE: The array is created but NOT filled!


write

public void write(java.lang.String pData)
Write a String to the OutputStream or Writer. No newline is appended, the String is sent as-is! If the String is null it is ignored. If empty but not null it is written. Any Exceptions are reported at Error level. Calling this method on an Input object has no effect.

Parameters:
pData - The String to send out.

write

public void write(int pData)
Write a single byte (OutputStream) or char (Writer) to the Output object. No effect on Input objects. Any errors are reported at Error level.

Parameters:
pData - The byte or char to write, the selection is automatic.

writeLine

public void writeLine(java.lang.String pLine)
Write a String per the plain write() method BUT append a newline (OutputStream) or call newLine() (Writer).


write

public void write(byte[] pData,
                  int pOffset,
                  int pLength)
Issue a write to the underlying OutputStream. This method DOES NOTHING if the IO Object is NOT an OutputStream!

Parameters:
pData - The array of bytes to write.
pOffset - The starting point within the array.
pLength - The number of bytes to write.

write

public void write(char[] pData,
                  int pOffset,
                  int pLength)
Issue a write to the underlying Writer. This method has NO EFFECT if the IO Object is NOT a Writer!

Parameters:
pData - The char[] array to write.
pOffset - The starting point within the array.
pLength - The number of bytes to write.

readLine

public java.lang.String readLine()
Read a line. Return is null if the IO object is not a Reader, there is no data, or an error occurs!


read

public int read()
Read a byte or char of data, depending on the IO Object. Returns -1 at the end of file or if an error occurs. Calling this method on an Output object always returns -1.


read

public int read(byte[] bData,
                int pOffset,
                int pLength)

Read a sequence of bytes into an array. The return value equals the number of bytes read UNLESS:

If any of these occur, the return value is -1

Parameters:
bData - Byte array into which to read the data.
pOffset - Location in the array to start writing.
pLength - The number of bytes to read.
Returns:
The number of bytes read, or -1.

read

public int read(char[] bData,
                int pOffset,
                int pLength)

Read a sequence of char into an array. The return value equals the number read UNLESS:

If any of these occur, the return value is -1

Parameters:
bData - Char array into which to read the data.
pOffset - Location in the array to start writing.
pLength - The number of bytes to read.
Returns:
The number of char read, or -1.