Zur Demonstration der index-sequentiellen Dateibearbeitung wird ein Programm herangezogen, das die Lebensdauer von Dateien auf einer Kennung überwacht. Das Programm erwartet zwei Parameter, die Benutzerkennung, die zu überwachen ist, und den Namen der Datei, in der das Programm die Daten hinterlegen kann. Beim ersten Aufruf sollte die Datei noch nicht existieren, dann wird sie mit den für das Programm korrekten Attributen angelegt.
Das Beispiel erzeugt als Datenbank eine ISAM-Datei mit fester Satzlänge. Die Fehlerbehandlung ist im Beispiel nicht besonders komfortabel ausgelegt, damit der dafür notwendige umfangreiche Code nicht von der eigentlichen Schnittstellennutzung ablenkt.
Das Programm befindet sich in der Datei FileHistory.java:
import java.io.*; import com.fujitsu.ts.jrio.*; import com.fujitsu.ts.jrio.DMS.AccessParameterISAM; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; /** * The demo program FileHistory provides a * simple mechanism to log changes in the files belonging * to a given BS2000 userid. In fact, only two dates are * logged for each file: date first seen and date last seen. * * Every time the program is started it synchronizes the * current list of filenames with the list of filenames * given by the logfile: * * New filenames are added to the logfile with date first seen * and date last seen set to the current date. * * For filenames of the current list which are already logged * the date last seen is updated. * * Filenames in the logfile which are no more in the current * list remain untouched. * * The program should run once a day, to create a complete * history. * * The interesting part of this program is the method * doFileHistory(), all other methods are added to make it * a complete executable program. */ public class FileHistory { /** * The main method, which analyses the program arguments, * calls the work method and provides global error * handling. */ public static void main(String args[]) { String userid = null; String logfilename = null; for (int i = 0; i < args.length; i++) { if (userid == null) userid = "$" + args[i] + "."; else if (logfilename == null) logfilename = args[i]; else usage(); } if (userid == null || logfilename == null) usage(); try { doFileHistory(userid,logfilename); } catch (Exception e) { error(e.toString()); } } /** * Print a usage message and exit with error */ private static void usage() { error("Usage: FileHistory userid logfile\n" + " - userid without '$' and '.'"); } /** * Print the given error message and exit */ private static void error(String msg) { System.err.println(msg); System.exit(1); } /** * The work method. * This method demonstrates, how the JRIO interfaces * may be used to update records in an ISAM file * * @param userid * the userid (with '$' and '.') to be scanned * @param logfilename * the file containing the log records */ public static void doFileHistory(String userid, String logfilename) throws IOException { /** * The current Date as string, * to be written to the log record */ DateFormat df = new SimpleDateFormat("yyyy.MM.dd"); String toDay = df.format(new Date()); /** * The directory to be scanned for additional or * deleted files in its canonical form */ RecordFile root = new RecordFile(userid,"DMS").getCanonicalFile(); /** * List of filenames within the scanned directory */ String[] rfList = root.list(); /** * Definition of file for logging */ RecordFile logfile = new RecordFile(logfilename,"DMS"); KeyedAccessRecordFile log = null; /** * key descriptor of the log file * and dummy key value (will be filled later * and used for reading) */ KeyDescriptor keyDesc = null; KeyValue keyVal = null; /** * Records from the logfile are read into this buffer. * It has fixed length: filename (54), * date fist seen (10), date last seen (10) */ Record logrec = new Record(54 + 10 + 10); /** * check if the logfile already exists * and prepare access parameter */ AccessParameterISAM accesspar; if (!logfile.exists()) { /* No, create it */ accesspar = (AccessParameterISAM) logfile.getDefaultAccessParameter("ISAM"); accesspar.setPrimaryKeyPosition(0); accesspar.setPrimaryKeyLength(54); accesspar.setRecordFormat( AccessParameter.RECORD_FORMAT_FIXED); accesspar.setRecordLength(54 + 10 + 10); if (logfile.createNewFile(accesspar) == false) error("Cannot create file " + logfilename); } else { accesspar = (AccessParameterISAM) logfile.getAccessParameter("ISAM"); } /** * Open the log file */ log = new KeyedAccessRecordFile( logfile,accesspar,KeyedAccessRecordFile.INOUT); /** * Get the key descriptor of the log file */ keyDesc = log.getPrimaryKeyDescriptor(); /** * Consistency check */ if (keyDesc.getPosition() != 0 || keyDesc.getLength() != 54) { log.close(); error("File " + logfile + " is no valid logfile."); } /** * create key value connected with key descriptor * proper values will be inserted later */ keyVal = new KeyValue(keyDesc); /** * loop through the list of filenames */ for (int i = 0; i < rfList.length; i++) { /** * prepare key vaue for reading the * log record for this filename */ keyVal.setStringValue(rfList[i]); /** * check if the filename is already in the log */ if (log.read(keyVal,logrec) > -1) { /** * yes, filename did exist at last run, * update 'date last seen' field */ logrec.setStringField(toDay,64,10); /** * write updated record back to logfile */ log.writeBack(logrec); } else { /** * filename is new: build a new record */ logrec.setKeyField(keyVal); logrec.setStringField(toDay,54,10); logrec.setStringField(toDay,64,10); /** * write new record to log file */ log.write(logrec); } } /** * close the logfile */ log.close(); } }
Das Programm kann mit dem Java-Compiler javac übersetzt und anschließend zum Ablauf gebracht werden. Es sind dabei keine besonderen Angaben notwendig, um die JRIO-Schnittstellen verfügbar zu haben.