Hi,
I am using this IBM manual as a reference to build a java program to invoke DfSort within java. Apparently there is only one dfSort.getChildStdoutStream() method which give the output stream for the sortout. Which makes me think we cant use OUTFIL,FNAMES= in the method dfSort.addControlStatement(""). If it can be used I want to get a separate getChildStdoutStream() for each of the output files. The sample java code given by IBM is below
http://www-01.ibm.com/support/knowledge ... oJava.htmlimport java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import com.ibm.jzos.DfSort;
import com.ibm.jzos.RcException;
import com.ibm.jzos.ZFile;
/**
* This example creates an instance of {@link DfSort} to sort an existing Dataset
* and read the sort output into Java.
* <p>
* Arguments (supplied as key=value pairs):
* <dl>
* <dt>sortin=<dsn></dt>
* <dd>The name of a RECFM=F dataset to sort. Supplied to DFSORT as SORTIN.</dd>
* <dt>[encoding=<codepage>]</dt>
* <dd>The character set of the SORTIN dataset. If not supplied, binary data is assumed.</dd>
* <dt>[shareas=<yes | no>]</dt>
* <dd>Determines that address space for DFSORT. If yes, DFSORT will run in the same address
* space as the JVM. If no, it will run in a separate address space.</dd>
* <dt>[loglevel=<n>]</dt>
* <dd>Sets the logging level for the child process and prints the resulting
* child process output is written to System.err. The valid levels are those defined
* in the ZUtil.LOG_* constants.</dd>
* </dl>
* <p>
* Features illustrated:
* <ul>
* <li>Specify an existing RECFM=F existing dataset as input (SORTIN) to DFSORT
* <li>Sort the records in Ascending order
* <li>Read the DFSORT (SORTOUT) results and process in Java
* </ul>
*/
public class DfSortFixedDatasetToJava {
public static void main(String[] args) throws Exception {
DfSortArguments dfsortArgs = new DfSortArguments(args);
if ((dfsortArgs.getSortinDataset() == null)) {
System.err.println("Usage: " + DfSortFixedDatasetToJava.class.getName() + " sortin=<dsn> [encoding=<codepage>] [shareas=<yes|NO>]");
System.err.println("Where:");
System.err.println("\tsortin is a RECFM=F dataset");
System.err.println("\tencoding is the source character set. If not supplied, raw bytes are processed.");
System.err.println("\tshareas = yes: DFSORT executes in the same address space as the JVM");
System.exit(4);
}
DsInfo inDs = dfsortArgs.getSortinDataset();
if (!inDs.isFixedRecfm()) {
System.err.println("Dataset " + inDs.getFullyQualifiedDsn() + " is not RECFM=F");
System.exit(8);
}
doSort(dfsortArgs);
}
private static void doSort(DfSortArguments dfsortArgs) throws Exception {
DsInfo inDs = dfsortArgs.getSortinDataset();
DfSort dfSort = new DfSort();
if (dfsortArgs.getLogLevel() != -1) {
dfSort.setLoggingLevel(dfsortArgs.getLogLevel());
}
//Direct DFSORT to get its input (SORTIN) from the supplied dataset.
dfSort.addAllocation("alloc fi(sortin) da("+inDs.getFullyQualifiedDsn()+") reuse shr msg(2)");
//Direct DFSORT to write output the the output named pipe.
dfSort.setOutputStreamRecLen(inDs.getLrecl());
//For this example, we sort the entire record (starting in column 1 for
//a length of lrecl. The data is treated as character data (CH) and the
//results are in ascending order (A)
dfSort.addControlStatement("SORT FIELDS=(1,"+inDs.getLrecl()+",CH,A)");
//Specify whether the DFSORT child process should be run in a separate address space.
//This allows multiple DFSORT processes to run simultaneously as each instance of
//the DFSORT DDs (SORTIN, SORTOUT, etc...) will be in their own address space.
dfSort.setSameAddressSpace(dfsortArgs.isSameAddressSpace());
//Kick off the sort.
long startTime = System.currentTimeMillis();
dfSort.execute();
//Once the child starts, open a BufferedInputStream on the child process' stdout
//and read the sort result.
BufferedInputStream bis = new BufferedInputStream(dfSort.getChildStdoutStream());
byte[] bytes = new byte[inDs.getLrecl()];
int recordCount = 0;
while (readRecord(bis,bytes)) {
//Process data
if (dfsortArgs.getEncoding() != null) {
String line = new String(bytes,dfsortArgs.getEncoding());
//Process encoded string...
} else {
//Process raw bytes...
}
recordCount++;
}
bis.close();
//Wait for dfSort to finish and check the result
int rc =0;
try {
rc = dfSort.getReturnCode();
} catch (RcException rce) {
System.out.println("Caught RcException: " + rce.getMessage());
rc = -1;
}
long runtime = System.currentTimeMillis() - startTime;
if (rc != 0 || dfsortArgs.getLogLevel() >= 0) {
List stderrLines = dfSort.getStderrLines();
for (Iterator i=stderrLines.iterator(); i.hasNext(); ) {
System.err.println(i.next());
}
}
System.out.println("RC=" + rc + " TIME=" + runtime + " RECORD COUNT=" + recordCount + " "
+ DfSortFixedDatasetToJava.class.getName());
}
/*
* Read exactly bytesToRead from the underlying stream (this call may block). Throw
* an IOException if EOF is encountered before all of the bytes are read.
*/
private static boolean readRecord(InputStream is, byte[] bytes) throws IOException {
int offset = 0;
int bytesToRead = bytes.length;
int c = is.read();
if (c == -1) {
return false;
} else {
bytes[offset++] = (byte) c;
--bytesToRead;
}
while (bytesToRead > 0) {
int bytesRead = is.read(bytes, offset, bytesToRead);
if (bytesRead == -1) {
throw new IOException("EOF encountered before all record bytes read");
}
bytesToRead -= bytesRead;
offset += bytesRead;
}
return true;
}
}