使用FTP / FTPS将数据写入VB(可变块)文件

时间:2017-04-19 12:43:04

标签: java ftp mainframe

package base;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import com.ibm.jzos.ZFile;

public class FTPSVB {

public static void main(String[] args) {
    BufferedInputStream binp=null;
    BufferedOutputStream bout=null;

    String server, username, password, fileTgt, fileSrc;
    String protocol = "TLS";    // SSL/TLS
    FTPSClient ftps = new FTPSClient(protocol);
    FTPSClient ftps2 = new FTPSClient(protocol);
    server="***";
    username="***";
    password="***";
    fileSrc="ABC00T.SMP.SAVE.ULRL";
    fileTgt="ABC00T.SMP.SAVE.OUT.ULRL";
    try
    {
        int reply;
        ftps.connect(server);
        ftps2.connect(server);
        reply = ftps.getReplyCode();
        reply = ftps2.getReplyCode();
    }
    try
    {
        ftps.setBufferSize(200);
        ftps.setFileType(FTP.BINARY_FILE_TYPE); 
        if (!ftps.login(username, password))
        {
            ftps.logout();
            System.out.println("ERROR..");
            System.exit(-1);
        }
        ftps.execPBSZ(0);
        ftps.execPROT("P");

        ftps.enterLocalPassiveMode();
        ftps.setAutodetectUTF8(true);
        ftps.site("QUOTE RDW");
        ftps2.setBufferSize(200);
        ftps2.setFileType(FTP.BINARY_FILE_TYPE);    
        ftps2.site("QUOTE RDW");
        ftps2.site("QUOTE recfm=VB lrecl=106 blksize=27998");
        if (!ftps2.login(username, password))
        {
            ftps2.logout();
            System.out.println("ERROR..");
            System.exit(-1);
        }
        ftps2.execPBSZ(0);
        ftps2.execPROT("P");
        ftps2.enterLocalPassiveMode();
        ftps2.setAutodetectUTF8(true);
        binp=new BufferedInputStream(ftps.retrieveFileStream(fileSrc));
        bout=new BufferedOutputStream(ftps2.storeFileStream(fileTgt));
        final byte []bufLen= new byte[4];
        int readLen=binp.read(bufLen, 0, 4);// Read len
        int recCounter=1;
        while(readLen!=-1){
        ByteArrayInputStream ba2=new ByteArrayInputStream (bufLen,0,4);
            int z=ba2.read();
            int reclen=0;
            int li=0;
            while(z!=-1){
                if(li==0)
                    reclen+=z*256;
                else if(li==1)
                    reclen+=z;
                li++;
                z=ba2.read();
            }
            ba2.close();
            reclen-=4;
            byte []buf=new byte[reclen];
            readLen=binp.read(buf, 0, reclen);
            boolean isEOF=false;
            while(readLen<reclen) {
                int nextLen=binp.read(buf, readLen, reclen-readLen);
                if(nextLen==-1){// End of file is reached.
                    isEOF=true;
                    break;
                }
                readLen=readLen+nextLen;
            }
            String a=new String(buf, ZFile.DEFAULT_EBCDIC_CODE_PAGE);
            StringBuilder str=new StringBuilder(a);
            //str.append(System.getProperty("line.separator"));
            System.out.println(""+str);
      //appending extra space for record till its length matches file record length
           if(str.length()<102) {
                for (int i = str.length(); i < 102; i++) {
                    str.append(" ");
                }
            }
            byte []outBytes=new byte[102];
        outBytes=str.toString().getBytes(ZFile.DEFAULT_EBCDIC_CODE_PAGE);
            bout.write(outBytes);
            if(isEOF){
                break;
            }
            readLen=binp.read(bufLen, 0, 4);// Read length- RDW 
            recCounter++;
        }
        bout.flush();
        bout.close();
        binp.close();
        ftps.completePendingCommand();
        ftps2.completePendingCommand();
        ftps.logout();
    }
    catch (FTPConnectionClosedException e)
    {
        System.err.println("Server closed connection.");
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    finally
    {
        if (ftps.isConnected())
        {
            try
            {
                ftps.disconnect();
            }
            catch (IOException f)
            {
                // do nothing
                f.printStackTrace();
            }
        }
    }
    }
 }

我使用上面的代码来读写VB文件。我能够读取变量块记录。但是在写作的时候,如果我不附加额外的空间来匹配文件记录长度,那么数据就会变得混乱。如果我为它添加额外的空间,它会消耗大量内存。我在这里错过了什么吗?我该如何解决这个问题呢?

1 个答案:

答案 0 :(得分:0)

我猜你的问题是ftps2.setFileType(FTP.BINARY_FILE_TYPE);

Windows / Unix / Linux文件对“记录”一无所知,每个文件只是一个字节流。处理文本文件时,流可能包含行尾字符(ASCII中为x0Ax0Dx0D0A。这些可能被解释为记录的结尾和新记录的开始,因此当大多数FTP工具在文本模式中遇到其中一个时会在z / OS端启动新记录(和反之亦然,在从 z / OS转移时开始新记录时添加一个。

对于二进制文件,事情有点不同,因为x0Dx0A没有以任何特殊方式处理,而只是两个字节值。

所以为了获得你想要的东西,你有这些可能性:

  1. 使用文本模式传输文件,但这可能会导致某种代码页转换。如果可能,您可以配置完全不进行转换的自定义转换表。
  2. 将二进制文件传输到某个FB数据集并编写工具,将连续字节流拆分为正确的行终止字符,并将结果记录写入VB数据集。